View Javadoc
1 /* 2 * Scope: a generic MVC framework. 3 * Copyright (c) 2000-2002, The Scope team 4 * All rights reserved. 5 * 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * Neither the name "Scope" nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR 27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * 35 * 36 * $Id: STable.java,v 1.22 2002/09/13 17:04:41 ludovicc Exp $ 37 */ 38 package org.scopemvc.view.swing; 39 40 41 import java.awt.Component; 42 import java.awt.event.MouseEvent; 43 import java.awt.event.MouseListener; 44 import java.math.BigDecimal; 45 import java.math.BigInteger; 46 import java.util.HashMap; 47 import javax.swing.DefaultCellEditor; 48 import javax.swing.JCheckBox; 49 import javax.swing.JLabel; 50 import javax.swing.JTable; 51 import javax.swing.JToolTip; 52 import javax.swing.ListSelectionModel; 53 import javax.swing.table.TableCellEditor; 54 import javax.swing.table.TableCellRenderer; 55 import javax.swing.table.TableModel; 56 import org.apache.commons.logging.Log; 57 import org.apache.commons.logging.LogFactory; 58 import org.scopemvc.core.Control; 59 import org.scopemvc.core.Controller; 60 import org.scopemvc.core.Selector; 61 import org.scopemvc.core.View; 62 63 /*** 64 * <P> 65 * 66 * A JTable bound to a list property of a model. The table shows a list of rows 67 * from the bound property (see {@link #setSelector}). If the rows are model 68 * objects, the properties shown for each column are set using {@link 69 * #setColumnSelectors}. See also {@link #setColumnNames}. </P> <P> 70 * 71 * STable uses {@link STableModel} and so the contents can be sorted using 72 * {@link SAbstractListModel#setSorted(boolean) setSorted(boolean)} or {@link 73 * SAbstractListModel#setSorted(java.util.Comparator) setSorted(Comparator)}. 74 * </P> <P> 75 * 76 * STable uses a standard (non-bound) Swing ListSelectionModel unless a 77 * selection Selector is set using {@link #setSelectionSelector} or {@link 78 * #setSelectionSelectorString} in which case a bound SListSelectionModel is 79 * used. This allows both single-selection and an as-yet-limited multiselection 80 * (contiguous only) using a HashSet property to hold the selected objects. See 81 * {@link SListSelectionModel}, which is used by STable to maintain bound 82 * selections. </P> 83 * 84 * @author <A HREF="mailto:daniel.michalik@autel.cz">Daniel Michalik</A> 85 * @author <A HREF="mailto:smeyfroi@users.sourceforge.net">Steve Meyfroidt</A> 86 * @created 05 September 2002 87 * @version $Revision: 1.22 $ $Date: 2002/09/13 17:04:41 $ 88 */ 89 public class STable extends JTable 90 implements View, Refreshable, MouseListener, ListSelectionParent { 91 92 private static final Log LOG = LogFactory.getLog(STable.class); 93 94 // --------------------- Default renderer and editors --------------------- 95 96 /*** 97 * TODO: describe of the Field 98 */ 99 protected HashMap editors; 100 101 // ------------- Support validation failures from selection ------------- 102 103 /*** 104 * Helper to manage validation state. 105 */ 106 private ValidationHelper validationHelper = new ValidationHelper(this); 107 108 // -------------------- Controls ----------------------- 109 110 /*** 111 * Control to issue on selection change. 112 */ 113 private String selectionControlID; 114 115 /*** 116 * Control to issue on double click. 117 */ 118 private String doubleClickControlID; 119 120 121 /*** 122 * Constructor for the STable object 123 */ 124 public STable() { 125 super(null, null, null); 126 // single selection only for now 127 // setAutoCreateColumnsFromModel(false); 128 addMouseListener(this); 129 } 130 131 132 // protected ListSelectionModel createDefaultSelectionModel() { 133 // return new SListSelectionModel(this); 134 // } 135 136 137 // ------------------ Implement View by delegation to STableModel and selection 138 139 140 /*** 141 * Gets the bound model 142 * 143 * @return The boundModel value 144 */ 145 public final Object getBoundModel() { 146 return ((STableModel) getModel()).getBoundModel(); 147 } 148 149 150 // --------- Set up table binding by delegation ------------- 151 152 /*** 153 * Gets the selector 154 * 155 * @return The selector value 156 */ 157 public final Selector getSelector() { 158 return ((STableModel) getModel()).getSelector(); 159 } 160 161 162 /*** 163 * Gets the selection selector 164 * 165 * @return The selectionSelector value 166 */ 167 public final Selector getSelectionSelector() { 168 return ((SListSelectionModel) getSelectionModel()).getSelector(); 169 } 170 171 172 /*** 173 * TODO: document the method 174 */ 175 public void issueChangeSelectionControl() { 176 if (selectionControlID != null) { 177 Control control = new Control(selectionControlID); 178 issueControl(control); 179 } 180 } 181 182 183 /*** 184 * Get the Control ID for the Control that will be issued when the selection 185 * is changed. 186 * 187 * @return The changeSelectionControlID value 188 */ 189 public String getChangeSelectionControlID() { 190 return selectionControlID; 191 } 192 193 194 /*** 195 * Get the Control ID for the Control that will be issued when the List is 196 * double-clicked. 197 * 198 * @return The doubleClickControlID value 199 */ 200 public String getDoubleClickControlID() { 201 return doubleClickControlID; 202 } 203 204 205 /*** 206 * Don't assign a direct Controller to List, instead delegate to the 207 * containing SwingView that has a parent Controller. 208 * 209 * @return The controller value 210 */ 211 public Controller getController() { 212 return null; 213 } 214 215 216 /*** 217 * Don't assign a direct Controller to List, instead delegate to the 218 * containing SwingView that has a parent Controller. 219 * 220 * @param inControl TODO: Describe the Parameter 221 */ 222 public void issueControl(Control inControl) { 223 SwingUtil.issueControl(this, inControl); 224 } 225 226 227 // public TableCellEditor getCellEditor(int row, int column) { 228 // Class clazz = getModel().getColumnClass(column); 229 // TableCellEditor result = (TableCellEditor)editors.get(clazz); 230 // if (LOG.isDebugEnabled()) LOG.debug("getCellEditor: " + result); 231 // if (result == null) { 232 // result = new STableTextCellEditor(clazz); 233 // } 234 // return result; 235 // } 236 237 238 /*** 239 * Gets the default editor 240 * 241 * @param columnClass TODO: Describe the Parameter 242 * @return The defaultEditor value 243 */ 244 public TableCellEditor getDefaultEditor(Class columnClass) { 245 if (columnClass == null) { 246 return null; 247 } else { 248 Object editor = editors.get(columnClass); 249 if (editor != null) { 250 return (TableCellEditor) editor; 251 } else { 252 return new STableTextCellEditor(columnClass); 253 // getDefaultEditor(columnClass.getSuperclass()); 254 } 255 } 256 } 257 258 259 /*** 260 * Gets the default renderer 261 * 262 * @param columnClass TODO: Describe the Parameter 263 * @return The defaultRenderer value 264 */ 265 public TableCellRenderer getDefaultRenderer(Class columnClass) { 266 if (columnClass == null) { 267 return null; 268 } else { 269 Object renderer = super.getDefaultRenderer(columnClass); 270 if (renderer != null) { 271 return (TableCellRenderer) renderer; 272 } else { 273 return new SDefaultTableCellRenderer(columnClass); 274 // getDefaultRenderer(columnClass.getSuperclass()); 275 } 276 } 277 } 278 279 280 /*** 281 * Sets the bound model 282 * 283 * @param inModel The new boundModel value 284 */ 285 public final void setBoundModel(Object inModel) { 286 ((STableModel) getModel()).setBoundModel(inModel); 287 if (getSelectionModel() instanceof SListSelectionModel) { 288 ((SListSelectionModel) getSelectionModel()).setBoundModel(inModel); 289 } 290 } 291 292 /*** 293 * Set the Selector for the table data. Should be a java.util.List or an 294 * Object[] or have a "size" property and properties accessible by an 295 * IntIndexedSelector. 296 * 297 * @param inSelector The new selector value 298 */ 299 public final void setSelector(Selector inSelector) { 300 ((STableModel) getModel()).setSelector(inSelector); 301 } 302 303 304 /*** 305 * Set the Selector for the table data. Should be a java.util.List or an 306 * Object[] or have a "size" property and properties accessible by an 307 * IntIndexedSelector. 308 * 309 * @param inSelectorString The new selectorString value 310 */ 311 public final void setSelectorString(String inSelectorString) { 312 ((STableModel) getModel()).setSelectorString(inSelectorString); 313 } 314 315 /*** 316 * Set the Selector for the list selection: this property will be bound to 317 * the list's single selection. 318 * 319 * @param inSelector The new selectionSelector value 320 */ 321 public final void setSelectionSelector(Selector inSelector) { 322 if (inSelector != null) { 323 setSelectionModel(new SListSelectionModel(this)); 324 ((SListSelectionModel) getSelectionModel()).setSelector(inSelector); 325 } else { 326 setSelectionModel(createDefaultSelectionModel()); 327 } 328 } 329 330 331 /*** 332 * Set the Selector for the list selection: this property will be bound to 333 * the list's single selection. 334 * 335 * @param inSelectorString The new selectionSelectorString value 336 */ 337 public final void setSelectionSelectorString(String inSelectorString) { 338 if (inSelectorString != null) { 339 setSelectionModel(new SListSelectionModel(this)); 340 ((SListSelectionModel) getSelectionModel()).setSelectorString(inSelectorString); 341 } else { 342 setSelectionModel(createDefaultSelectionModel()); 343 } 344 } 345 346 347 /*** 348 * Set the Control ID for the Control that will be issued when the selection 349 * is changed. If null no Control will be issued. 350 * 351 * @param inControlID The new changeSelectionControlID value 352 */ 353 public final void setChangeSelectionControlID(String inControlID) { 354 selectionControlID = inControlID; 355 } 356 357 /*** 358 * Set the Control ID for the Control that will be issued when the List is 359 * double-clicked. If null no Control will be issued. 360 * 361 * @param inControlID The new doubleClickControlID value 362 */ 363 public final void setDoubleClickControlID(String inControlID) { 364 doubleClickControlID = inControlID; 365 } 366 367 368 /*** 369 * Set up the column selectors. 370 * 371 * @param inSelectors The new columnSelectors value 372 */ 373 public void setColumnSelectors(Selector[] inSelectors) { 374 ((STableModel) getModel()).setColumnSelectors(inSelectors); 375 createDefaultColumnsFromModel(); 376 } 377 378 379 /*** 380 * Set up the column selectors. 381 * 382 * @param inSelectorStrings The new columnSelectorStrings value 383 */ 384 public void setColumnSelectorStrings(String[] inSelectorStrings) { 385 ((STableModel) getModel()).setColumnSelectorStrings(inSelectorStrings); 386 createDefaultColumnsFromModel(); 387 } 388 389 390 /*** 391 * Set up the column names. 392 * 393 * @param inNames The new columnNames value 394 */ 395 public void setColumnNames(String[] inNames) { 396 ((STableModel) getModel()).setColumnNames(inNames); 397 createDefaultColumnsFromModel(); 398 } 399 400 /*** 401 * Don't assign a Controller to this component, instead delegate to the 402 * containing SwingView that has a parent Controller. 403 * 404 * @param inController The new controller value 405 */ 406 public void setController(Controller inController) { 407 throw new UnsupportedOperationException("Can't assign a Controller to a " + getClass()); 408 } 409 410 // ------------------ Refreshable ------------------------- 411 412 /*** 413 * TODO: document the method 414 */ 415 public void refresh() { 416 ((STableModel) getModel()).refresh(); 417 refreshSelection(); 418 } 419 420 421 // ------------- Support maintaining selection when list data changes ---------- 422 423 /*** 424 * TODO: document the method 425 */ 426 public void refreshSelection() { 427 ListSelectionModel s = getSelectionModel(); 428 if (s instanceof SListSelectionModel) { 429 ((SListSelectionModel) s).refresh(); 430 } 431 } 432 433 434 // ------------- Implement SingleListSelectionParent ---------------- 435 436 /*** 437 * @param inValue TODO: Describe the Parameter 438 * @return -1 if not found. 439 */ 440 public int findIndexFor(Object inValue) { 441 if (inValue == null) { 442 return -1; 443 } 444 for (int i = getModel().getRowCount() - 1; i >= 0; --i) { 445 if (inValue.equals(((SAbstractListModel) getModel()).getElementAt(i))) { 446 return i; 447 } 448 } 449 return -1; 450 } 451 452 453 /*** 454 * @param inIndex TODO: Describe the Parameter 455 * @return null if not found. 456 */ 457 public Object findElementAt(int inIndex) { 458 if (inIndex < 0) { 459 return null; 460 } 461 try { 462 return ((SAbstractListModel) getModel()).getElementAt(inIndex); 463 } catch (Exception e) { 464 LOG.warn("Can't findElementAt: " + inIndex, e); 465 } 466 return null; 467 } 468 469 470 /*** 471 * TODO: document the method 472 * 473 * @param inException TODO: Describe the Parameter 474 */ 475 public void validationFailed(Exception inException) { 476 validationHelper.validationFailed(inException); 477 } 478 479 480 /*** 481 * TODO: document the method 482 */ 483 public void validationSuccess() { 484 validationHelper.validationSuccess(); 485 } 486 487 488 /*** 489 * TODO: document the method 490 * 491 * @return TODO: Describe the Return Value 492 */ 493 public JToolTip createToolTip() { 494 return validationHelper.createToolTip(super.createToolTip()); 495 } 496 497 498 /*** 499 * TODO: document the method 500 * 501 * @param e TODO: Describe the Parameter 502 */ 503 public void mouseClicked(MouseEvent e) { 504 if (e.getClickCount() == 2) { 505 if (doubleClickControlID != null) { 506 Control control = new Control(doubleClickControlID); 507 issueControl(control); 508 } 509 } 510 } 511 512 513 /*** 514 * TODO: document the method 515 * 516 * @param e TODO: Describe the Parameter 517 */ 518 public void mousePressed(MouseEvent e) { } 519 520 /*** 521 * TODO: document the method 522 * 523 * @param e TODO: Describe the Parameter 524 */ 525 public void mouseReleased(MouseEvent e) { } 526 527 /*** 528 * TODO: document the method 529 * 530 * @param e TODO: Describe the Parameter 531 */ 532 public void mouseEntered(MouseEvent e) { } 533 534 /*** 535 * TODO: document the method 536 * 537 * @param e TODO: Describe the Parameter 538 */ 539 public void mouseExited(MouseEvent e) { } 540 541 542 /*** 543 * STables create their own STableModel by default. 544 * 545 * @return TODO: Describe the Return Value 546 */ 547 protected TableModel createDefaultDataModel() { 548 return new STableModel(this); 549 } 550 551 552 /*** 553 * Sets default Scope table cell renderers. They use Scope's 554 * StringConverters. 555 */ 556 protected void createDefaultRenderers() { 557 if (LOG.isDebugEnabled()) { 558 LOG.debug("create DefaultRenderers for STable"); 559 } 560 561 super.createDefaultRenderers(); 562 // else updateUI() fails in superclass 563 564 setDefaultRenderer(Boolean.class, new BooleanRenderer()); 565 setDefaultRenderer(Boolean.TYPE, new BooleanRenderer()); 566 567 SDefaultTableCellRenderer rend = new SDefaultTableCellRenderer(Double.class); 568 rend.setHorizontalAlignment(JLabel.RIGHT); 569 setDefaultRenderer(Double.class, rend); 570 setDefaultRenderer(Double.TYPE, rend); 571 572 rend = new SDefaultTableCellRenderer(Float.class); 573 rend.setHorizontalAlignment(JLabel.RIGHT); 574 setDefaultRenderer(Float.class, rend); 575 setDefaultRenderer(Float.TYPE, rend); 576 577 rend = new SDefaultTableCellRenderer(Integer.class); 578 rend.setHorizontalAlignment(JLabel.RIGHT); 579 setDefaultRenderer(Integer.class, rend); 580 setDefaultRenderer(Integer.TYPE, rend); 581 582 rend = new SDefaultTableCellRenderer(Long.class); 583 rend.setHorizontalAlignment(JLabel.RIGHT); 584 setDefaultRenderer(Long.class, rend); 585 setDefaultRenderer(Long.TYPE, rend); 586 587 rend = new SDefaultTableCellRenderer(BigInteger.class); 588 rend.setHorizontalAlignment(JLabel.RIGHT); 589 setDefaultRenderer(BigInteger.class, rend); 590 591 rend = new SDefaultTableCellRenderer(BigDecimal.class); 592 rend.setHorizontalAlignment(JLabel.RIGHT); 593 setDefaultRenderer(BigDecimal.class, rend); 594 } 595 596 597 /*** 598 * TODO: document the method 599 */ 600 protected void createDefaultEditors() { 601 602 super.createDefaultEditors(); 603 // else updateUI() fails in superclass 604 605 editors = new HashMap(); 606 607 editors.put(Boolean.class, new BooleanEditor()); 608 editors.put(Boolean.TYPE, new BooleanEditor()); 609 } 610 611 612 static class BooleanRenderer extends JCheckBox implements TableCellRenderer { 613 /*** 614 * Constructor for the BooleanRenderer object 615 */ 616 public BooleanRenderer() { 617 super(); 618 setHorizontalAlignment(JLabel.CENTER); 619 } 620 621 /*** 622 * Gets the table cell renderer component 623 * 624 * @param table TODO: Describe the Parameter 625 * @param value TODO: Describe the Parameter 626 * @param isSelected TODO: Describe the Parameter 627 * @param hasFocus TODO: Describe the Parameter 628 * @param row TODO: Describe the Parameter 629 * @param column TODO: Describe the Parameter 630 * @return The tableCellRendererComponent value 631 */ 632 public Component getTableCellRendererComponent(JTable table, Object value, 633 boolean isSelected, boolean hasFocus, int row, int column) { 634 if (isSelected) { 635 setForeground(table.getSelectionForeground()); 636 super.setBackground(table.getSelectionBackground()); 637 } else { 638 setForeground(table.getForeground()); 639 setBackground(table.getBackground()); 640 } 641 setSelected((value != null && ((Boolean) value).booleanValue())); 642 return this; 643 } 644 } 645 646 647 static class BooleanEditor extends DefaultCellEditor { 648 /*** 649 * Constructor for the BooleanEditor object 650 */ 651 public BooleanEditor() { 652 super(new JCheckBox()); 653 JCheckBox checkBox = (JCheckBox) getComponent(); 654 checkBox.setHorizontalAlignment(JCheckBox.CENTER); 655 } 656 } 657 }

This page was automatically generated by Maven