Source for javax.swing.table.JTableHeader

   1: /* JTableHeader.java --
   2:    Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.swing.table;
  40: 
  41: import gnu.classpath.NotImplementedException;
  42: 
  43: import java.awt.Color;
  44: import java.awt.Cursor;
  45: import java.awt.Dimension;
  46: import java.awt.Font;
  47: import java.awt.FontMetrics;
  48: import java.awt.Point;
  49: import java.awt.Rectangle;
  50: import java.awt.event.FocusListener;
  51: import java.beans.PropertyChangeListener;
  52: import java.util.Locale;
  53: 
  54: import javax.accessibility.Accessible;
  55: import javax.accessibility.AccessibleAction;
  56: import javax.accessibility.AccessibleComponent;
  57: import javax.accessibility.AccessibleContext;
  58: import javax.accessibility.AccessibleRole;
  59: import javax.accessibility.AccessibleSelection;
  60: import javax.accessibility.AccessibleStateSet;
  61: import javax.accessibility.AccessibleText;
  62: import javax.accessibility.AccessibleValue;
  63: import javax.swing.JComponent;
  64: import javax.swing.JTable;
  65: import javax.swing.UIManager;
  66: import javax.swing.event.ChangeEvent;
  67: import javax.swing.event.ListSelectionEvent;
  68: import javax.swing.event.TableColumnModelEvent;
  69: import javax.swing.event.TableColumnModelListener;
  70: import javax.swing.plaf.TableHeaderUI;
  71: 
  72: /**
  73:  * Represents the table header. The header displays the column header values,
  74:  * is always visible event if the rest of the table scrolls up and down and
  75:  * supports column reordering and resizing with mouse.
  76:  */
  77: public class JTableHeader extends JComponent
  78:   implements TableColumnModelListener, Accessible
  79: {
  80:   protected class AccessibleJTableHeader extends AccessibleJComponent
  81:   {
  82:     protected class AccessibleJTableHeaderEntry extends AccessibleContext
  83:       implements Accessible, AccessibleComponent
  84:     {
  85:       public AccessibleJTableHeaderEntry(int c, JTableHeader p, JTable t)
  86:         throws NotImplementedException
  87:       {
  88:         throw new Error("not implemented");
  89:       }
  90:       
  91:       public void addFocusListener(FocusListener l)
  92:         throws NotImplementedException
  93:       {
  94:         throw new Error("not implemented");
  95:       }
  96:       
  97:       public void addPropertyChangeListener(PropertyChangeListener l)
  98:         throws NotImplementedException
  99:       {
 100:         throw new Error("not implemented");
 101:       }
 102:       
 103:       public boolean contains(Point p)
 104:         throws NotImplementedException
 105:       {
 106:         throw new Error("not implemented");
 107:       }
 108:       
 109:       public AccessibleAction getAccessibleAction()
 110:         throws NotImplementedException
 111:       {
 112:         throw new Error("not implemented");
 113:       }
 114:       
 115:       public Accessible getAccessibleAt(Point p)
 116:         throws NotImplementedException
 117:       {
 118:         throw new Error("not implemented");
 119:       }
 120:       
 121:       public Accessible getAccessibleChild(int i)
 122:         throws NotImplementedException
 123:       {
 124:         throw new Error("not implemented");
 125:       }
 126:       
 127:       public int getAccessibleChildrenCount()
 128:         throws NotImplementedException
 129:       {
 130:         throw new Error("not implemented");
 131:       }
 132:       
 133:       public AccessibleComponent getAccessibleComponent()
 134:         throws NotImplementedException
 135:       {
 136:         throw new Error("not implemented");
 137:       }
 138:       
 139:       public AccessibleContext getAccessibleContext()
 140:         throws NotImplementedException
 141:       {
 142:         throw new Error("not implemented");
 143:       }
 144:       
 145:       public String getAccessibleDescription()
 146:         throws NotImplementedException
 147:       {
 148:         throw new Error("not implemented");
 149:       }
 150:       
 151:       public int getAccessibleIndexInParent()
 152:         throws NotImplementedException
 153:       {
 154:         throw new Error("not implemented");
 155:       }
 156:       
 157:       public String getAccessibleName()
 158:         throws NotImplementedException
 159:       {
 160:         throw new Error("not implemented");
 161:       }
 162:       
 163:       public AccessibleRole getAccessibleRole()
 164:         throws NotImplementedException
 165:       {
 166:         throw new Error("not implemented");
 167:       }
 168:       
 169:       public AccessibleSelection getAccessibleSelection()
 170:         throws NotImplementedException
 171:       {
 172:         throw new Error("not implemented");
 173:       }
 174:       
 175:       public AccessibleStateSet getAccessibleStateSet()
 176:         throws NotImplementedException
 177:       {
 178:         throw new Error("not implemented");
 179:       }
 180:       
 181:       public AccessibleText getAccessibleText()
 182:         throws NotImplementedException
 183:       {
 184:         throw new Error("not implemented");
 185:       }
 186:       
 187:       public AccessibleValue getAccessibleValue()
 188:         throws NotImplementedException
 189:       {
 190:         throw new Error("not implemented");
 191:       }
 192:       
 193:       public Color getBackground()
 194:         throws NotImplementedException
 195:       {
 196:         throw new Error("not implemented");
 197:       }
 198:       
 199:       public Rectangle getBounds()
 200:         throws NotImplementedException
 201:       {
 202:         throw new Error("not implemented");
 203:       }
 204:       
 205:       public Cursor getCursor()
 206:         throws NotImplementedException
 207:       {
 208:         throw new Error("not implemented");
 209:       }
 210:       
 211:       public Font getFont()
 212:         throws NotImplementedException
 213:       {
 214:         throw new Error("not implemented");
 215:       }
 216:       
 217:       public FontMetrics getFontMetrics(Font f)
 218:         throws NotImplementedException
 219:       {
 220:         throw new Error("not implemented");
 221:       }
 222:       
 223:       public Color getForeground()
 224:         throws NotImplementedException
 225:       {
 226:         throw new Error("not implemented");
 227:       }
 228:       
 229:       public Locale getLocale()
 230:         throws NotImplementedException
 231:       {
 232:         throw new Error("not implemented");
 233:       }
 234:       
 235:       public Point getLocation()
 236:         throws NotImplementedException
 237:       {
 238:         throw new Error("not implemented");
 239:       }
 240:       
 241:       public Point getLocationOnScreen()
 242:         throws NotImplementedException
 243:       {
 244:         throw new Error("not implemented");
 245:       }
 246:       
 247:       public Dimension getSize()
 248:         throws NotImplementedException
 249:       {
 250:         throw new Error("not implemented");
 251:       }
 252:       
 253:       public boolean isEnabled()
 254:         throws NotImplementedException
 255:       {
 256:         throw new Error("not implemented");
 257:       }
 258:       
 259:       public boolean isFocusTraversable()
 260:         throws NotImplementedException
 261:       {
 262:         throw new Error("not implemented");
 263:       }
 264:       
 265:       public boolean isShowing()
 266:         throws NotImplementedException
 267:       {
 268:         throw new Error("not implemented");
 269:       }
 270:       
 271:       public boolean isVisible()
 272:         throws NotImplementedException
 273:       {
 274:         throw new Error("not implemented");
 275:       }
 276:       
 277:       public void removeFocusListener(FocusListener l)
 278:         throws NotImplementedException
 279:       {
 280:         throw new Error("not implemented");
 281:       }
 282:       
 283:       public void removePropertyChangeListener(PropertyChangeListener l)
 284:         throws NotImplementedException
 285:       {
 286:         throw new Error("not implemented");
 287:       }
 288:       
 289:       public void requestFocus()
 290:         throws NotImplementedException
 291:       {
 292:         throw new Error("not implemented");
 293:       }
 294:       
 295:       public void setAccessibleDescription(String s)
 296:         throws NotImplementedException
 297:       {
 298:         throw new Error("not implemented");
 299:       }
 300:       
 301:       public void setAccessibleName(String s)
 302:         throws NotImplementedException
 303:       {
 304:         throw new Error("not implemented");
 305:       }
 306:       
 307:       public void setBackground(Color c)
 308:         throws NotImplementedException
 309:       {
 310:         throw new Error("not implemented");
 311:       }
 312:       
 313:       public void setBounds(Rectangle r)
 314:         throws NotImplementedException
 315:       {
 316:         throw new Error("not implemented");
 317:       }
 318:       
 319:       public void setCursor(Cursor c)
 320:         throws NotImplementedException
 321:       {
 322:         throw new Error("not implemented");
 323:       }
 324:       
 325:       public void setEnabled(boolean b)
 326:         throws NotImplementedException
 327:       {
 328:         throw new Error("not implemented");
 329:       }
 330:       
 331:       public void setFont(Font f)
 332:         throws NotImplementedException
 333:       {
 334:         throw new Error("not implemented");
 335:       }
 336:       
 337:       public void setForeground(Color c)
 338:         throws NotImplementedException
 339:       {
 340:         throw new Error("not implemented");
 341:       }
 342:       
 343:       public void setLocation(Point p)
 344:         throws NotImplementedException
 345:       {
 346:         throw new Error("not implemented");
 347:       }
 348:       
 349:       public void setSize(Dimension d)
 350:         throws NotImplementedException
 351:       {
 352:         throw new Error("not implemented");
 353:       }
 354:       
 355:       public void setVisible(boolean b)
 356:         throws NotImplementedException
 357:       {
 358:         throw new Error("not implemented");
 359:       }
 360:     };
 361:   }
 362:   
 363:   /**
 364:    * Use serialVersionUid for interoperability.
 365:    */
 366:   private static final long serialVersionUID = 5144633983372967710L;
 367: 
 368:   /**
 369:    * The columnModel property.
 370:    */
 371:   protected TableColumnModel columnModel;
 372: 
 373:   /**
 374:    * The draggedColumn property.
 375:    */
 376:   protected TableColumn draggedColumn;
 377: 
 378:   /**
 379:    * The draggedDistance property.
 380:    */
 381:   protected int draggedDistance;
 382: 
 383:   /**
 384:    * The opaque property.
 385:    */
 386:   boolean opaque;
 387: 
 388:   /**
 389:    * The reorderingAllowed property.
 390:    */
 391:   protected boolean reorderingAllowed;
 392: 
 393:   /**
 394:    * The resizingAllowed property.
 395:    */
 396:   protected boolean resizingAllowed = true;
 397: 
 398:   /**
 399:    * The resizingColumn property.
 400:    */
 401:   protected TableColumn resizingColumn;
 402: 
 403:   /**
 404:    * The table property.
 405:    */
 406:   protected JTable table;
 407: 
 408:   /**
 409:    * The updateTableInRealTime property.
 410:    */
 411:   protected boolean updateTableInRealTime;
 412: 
 413:   TableCellRenderer cellRenderer; 
 414: 
 415:   /**
 416:    * Creates a new default instance.
 417:    */
 418:   public JTableHeader()
 419:   {
 420:     this(null);
 421:   }
 422: 
 423:   /**
 424:    * Creates a new header.  If <code>cm</code> is <code>null</code>, a new
 425:    * table column model is created by calling 
 426:    * {@link #createDefaultColumnModel()}.
 427:    * 
 428:    * @param cm  the table column model (<code>null</code> permitted).
 429:    */
 430:   public JTableHeader(TableColumnModel cm)
 431:   {
 432:     columnModel = cm == null ? createDefaultColumnModel() : cm; 
 433:     initializeLocalVars();
 434:     updateUI();
 435:   }
 436: 
 437:   /**
 438:    * Creates a default table column model.
 439:    * 
 440:    * @return A default table column model.
 441:    */
 442:   protected TableColumnModel createDefaultColumnModel()
 443:   {
 444:     return new DefaultTableColumnModel();
 445:   }
 446: 
 447:   /**
 448:    * Get the value of the {@link #accessibleContext} property.
 449:    *
 450:    * @return The current value of the property
 451:    */
 452:   public AccessibleContext getAccessibleContext()
 453:   {
 454:     return accessibleContext;
 455:   }
 456: 
 457:   /**
 458:    * Get the value of the {@link #columnModel} property.
 459:    *
 460:    * @return The current value of the property
 461:    */
 462:   public TableColumnModel getColumnModel()
 463:   {
 464:     return columnModel;
 465:   }
 466: 
 467:   /**
 468:    * Get the column that is currently being dragged. This is used when
 469:    * handling the column reordering with mouse.
 470:    *
 471:    * @return the column being dragged, null if none.
 472:    */
 473:   public TableColumn getDraggedColumn()
 474:   {
 475:     return draggedColumn;
 476:   }
 477: 
 478:   /**
 479:    * Get the value of the {@link #draggedDistance} property.
 480:    *
 481:    * @return The current value of the property
 482:    */
 483:   public int getDraggedDistance()
 484:   {
 485:     return draggedDistance;
 486:   }
 487: 
 488:   /**
 489:    * Check if it is possible to reorder the table columns by dragging column
 490:    * header with mouse. The table reordering is enabled by default, but can be
 491:    * disabled with {@link #setReorderingAllowed(boolean)}.
 492:    *
 493:    * @return true if reordering is allowed, false otherwise.
 494:    */ 
 495:   public boolean getReorderingAllowed()
 496:   {
 497:     return reorderingAllowed;
 498:   }
 499: 
 500:   /**
 501:    * Check if it is possible to resize the table columns by dragging the column
 502:    * boundary in the table header with mouse. The resizing is enabled
 503:    * by default, but can be disabled with {@link #setResizingAllowed(boolean)}.
 504:    *
 505:    * @return true if resizing is allowed, false otherwise.
 506:    */ 
 507:   public boolean getResizingAllowed()
 508:   {
 509:     return resizingAllowed;
 510:   }
 511: 
 512:   /**
 513:    * Get the column that is currently being resized. This is used when
 514:    * handling the column resizing with mouse.
 515:    *
 516:    * @return the column being currently resized, null if none.
 517:    */
 518:   public TableColumn getResizingColumn()
 519:   {
 520:     return resizingColumn;
 521:   }
 522: 
 523:   /**
 524:    * Get the table, having this header.
 525:    *
 526:    * @return the table, having this header.
 527:    */
 528:   public JTable getTable()
 529:   {
 530:     return table;
 531:   }
 532: 
 533:   /**
 534:    * Get the value of the {@link #updateTableInRealTime} property.
 535:    *
 536:    * @return The current value of the property
 537:    */
 538:   public boolean getUpdateTableInRealTime()
 539:   {
 540:     return updateTableInRealTime;
 541:   }
 542: 
 543:   /**
 544:    * Get the value of the {@link #opaque} property.
 545:    *
 546:    * @return The current value of the property
 547:    */
 548:   public boolean isOpaque()
 549:   {
 550:     return opaque;
 551:   }
 552: 
 553:   /**
 554:    * Set the value of the {@link #columnModel} property.
 555:    *
 556:    * @param c The new value of the property
 557:    */ 
 558:   public void setColumnModel(TableColumnModel c)
 559:   {
 560:     columnModel.removeColumnModelListener(this);
 561:     columnModel = c;
 562:     columnModel.addColumnModelListener(this);
 563:   }
 564: 
 565:   /**
 566:    * Set the column that is currently being dragged. This is used when
 567:    * dragging the column with mouse. Setting to null will stop the 
 568:    * dragging session immediately.
 569:    *
 570:    * @param draggingIt the column being currently dragged, null if none.
 571:    */ 
 572:   public void setDraggedColumn(TableColumn draggingIt)
 573:   {
 574:     draggedColumn = draggingIt;
 575:   }
 576: 
 577:   /**
 578:    * Set the value of the {@link #draggedDistance} property.
 579:    *
 580:    * @param d The new value of the property
 581:    */ 
 582:   public void setDraggedDistance(int d)
 583:   {
 584:     draggedDistance = d;
 585:   }
 586: 
 587:   /**
 588:    * Set the value of the {@link #opaque} property.
 589:    *
 590:    * @param o The new value of the property
 591:    */ 
 592:   public void setOpaque(boolean o)
 593:   {
 594:     opaque = o;
 595:   }
 596: 
 597:   /**
 598:    * Set the table ability to reorder columns by dragging column header
 599:    * with mouse. The table reordering is enabled by default, but can be
 600:    * disabled with this method.
 601:    *
 602:    * @param allowed true if reordering is allowed, false otherwise.
 603:    */ 
 604:   public void setReorderingAllowed(boolean allowed)
 605:   {
 606:     reorderingAllowed = allowed;
 607:   }
 608: 
 609:   /**
 610:    * Set the table ability to resize columns by dragging the column
 611:    * boundary in the table header with mouse. The resizing is enabled
 612:    * by default, but can be disabled using this method.
 613:    *
 614:    * @param allowed true if resizing is allowed, false otherwise.
 615:    */ 
 616:   public void setResizingAllowed(boolean allowed)
 617:   {
 618:     resizingAllowed = allowed;
 619:   }
 620: 
 621:   /**
 622:    * The the column that is currently being resized. This property is used
 623:    * when handling table resizing with mouse. Setting to null would stop
 624:    * the resizing session immediately.
 625:    *
 626:    * @param resizingIt the column being currently resized
 627:    */ 
 628:   public void setResizingColumn(TableColumn resizingIt)
 629:   {
 630:     resizingColumn = resizingIt;
 631:   }
 632: 
 633:   /**
 634:    * Set the value of the {@link #table} property.
 635:    *
 636:    * @param t The new value of the property
 637:    */ 
 638:   public void setTable(JTable t)
 639:   {
 640:     table = t;
 641:   }
 642: 
 643:   /**
 644:    * Set the value of the {@link #updateTableInRealTime} property.
 645:    *
 646:    * @param u The new value of the property
 647:    */ 
 648:   public void setUpdateTableInRealTime(boolean u)
 649:   {
 650:     updateTableInRealTime = u;
 651:   }
 652: 
 653:   /**
 654:    * Creates a default renderer.
 655:    * 
 656:    * @return A default renderer.
 657:    */
 658:   protected TableCellRenderer createDefaultRenderer()
 659:   {
 660:     return new DefaultTableCellRenderer();
 661:   }
 662:   
 663:   /**
 664:    * Returns the default table cell renderer.
 665:    * 
 666:    * @return The default table cell renderer.
 667:    */
 668:   public TableCellRenderer getDefaultRenderer()
 669:   {
 670:     return cellRenderer;
 671:   }
 672: 
 673:   /**
 674:    * Sets the default table cell renderer.
 675:    * 
 676:    * @param cellRenderer  the renderer.
 677:    */
 678:   public void setDefaultRenderer(TableCellRenderer cellRenderer)
 679:   {
 680:     this.cellRenderer = cellRenderer;
 681:   }
 682:   
 683:   /**
 684:    * Get the rectangle, occupied by the header of the given column.
 685:    * 
 686:    * @param column the column, for that the header area is requested.
 687:    * 
 688:    * @return the column header area.
 689:    */
 690:   public Rectangle getHeaderRect(int column)
 691:   {
 692:     Rectangle r = getTable().getCellRect(-1, column, false);
 693:     r.height = getHeight();
 694:     return r;
 695:   }
 696: 
 697:   protected String paramString()
 698:   {
 699:     return "JTableHeader";
 700:   }
 701: 
 702:   // UI support
 703: 
 704:   public String getUIClassID()
 705:   {
 706:     return "TableHeaderUI";
 707:   }
 708: 
 709:   public TableHeaderUI getUI()
 710:   {
 711:     return (TableHeaderUI) ui;
 712:   }
 713: 
 714:   public void setUI(TableHeaderUI u)
 715:   {
 716:     super.setUI(u);
 717:   }
 718: 
 719:   public void updateUI()
 720:   {
 721:     setUI((TableHeaderUI) UIManager.getUI(this));
 722:   }
 723: 
 724:   /**
 725:    * Returns the index of the column at the specified point.
 726:    * 
 727:    * @param point  the point.
 728:    * 
 729:    * @return The column index, or -1.
 730:    */
 731:   public int columnAtPoint(Point point)
 732:   {
 733:     if (getBounds().contains(point))
 734:       return columnModel.getColumnIndexAtX(point.x);
 735:     
 736:     return -1;
 737:   }
 738: 
 739:   /**
 740:    * Receives notification when a column is added to the column model.
 741:    *
 742:    * @param event the table column model event
 743:    */
 744:   public void columnAdded(TableColumnModelEvent event)
 745:   {
 746:     // TODO: What else to do here (if anything)?
 747:     resizeAndRepaint();
 748:   }
 749: 
 750:   /**
 751:    * Receives notification when a column margin changes in the column model.
 752:    *
 753:    * @param event the table column model event
 754:    */
 755:   public void columnMarginChanged(ChangeEvent event)
 756:   {
 757:     // TODO: What else to do here (if anything)?
 758:     resizeAndRepaint();
 759:   }
 760: 
 761:   /**
 762:    * Receives notification when a column is moved within the column model.
 763:    *
 764:    * @param event the table column model event
 765:    */
 766:   public void columnMoved(TableColumnModelEvent event)
 767:   {
 768:     // TODO: What else to do here (if anything)?
 769:     resizeAndRepaint();
 770:   }
 771: 
 772:   /**
 773:    * Receives notification when a column is removed from the column model.
 774:    *
 775:    * @param event the table column model event
 776:    */
 777:   public void columnRemoved(TableColumnModelEvent event)
 778:   {
 779:     // TODO: What else to do here (if anything)?
 780:     resizeAndRepaint();
 781:   }
 782: 
 783:   /**
 784:    * Receives notification when the column selection has changed.
 785:    *
 786:    * @param event the table column model event
 787:    */
 788:   public void columnSelectionChanged(ListSelectionEvent event)
 789:   {
 790:     // TODO: What else to do here (if anything)?
 791:     resizeAndRepaint();
 792:   }
 793: 
 794:   /**
 795:    * Validates the layout of this table header and repaints it. This is
 796:    * equivalent to <code>revalidate()</code> followed by
 797:    * <code>repaint()</code>.
 798:    */
 799:   public void resizeAndRepaint()
 800:   {
 801:     revalidate();
 802:     repaint();
 803:   }
 804: 
 805:   /**
 806:    * Initializes the fields and properties of this class with default values.
 807:    * This is called by the constructors.
 808:    */
 809:   protected void initializeLocalVars()
 810:   {
 811:     accessibleContext = new AccessibleJTableHeader();
 812:     draggedColumn = null;
 813:     draggedDistance = 0;
 814:     opaque = true;
 815:     reorderingAllowed = true;
 816:     resizingAllowed = true;
 817:     resizingColumn = null;
 818:     table = null;
 819:     updateTableInRealTime = true;
 820:     cellRenderer = createDefaultRenderer();
 821:   }
 822: }