Source for javax.swing.JTable

   1: /* JTable.java -- 
   2:    Copyright (C) 2002, 2004, 2005, 2006  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;
  40: 
  41: import java.awt.Color;
  42: import java.awt.Component;
  43: import java.awt.Cursor;
  44: import java.awt.Dimension;
  45: import java.awt.Font;
  46: import java.awt.FontMetrics;
  47: import java.awt.Point;
  48: import java.awt.Rectangle;
  49: import java.awt.event.FocusListener;
  50: import java.beans.PropertyChangeEvent;
  51: import java.beans.PropertyChangeListener;
  52: import java.text.DateFormat;
  53: import java.text.NumberFormat;
  54: import java.util.Date;
  55: import java.util.EventObject;
  56: import java.util.Hashtable;
  57: import java.util.Locale;
  58: import java.util.Vector;
  59: 
  60: import javax.accessibility.Accessible;
  61: import javax.accessibility.AccessibleComponent;
  62: import javax.accessibility.AccessibleContext;
  63: import javax.accessibility.AccessibleExtendedTable;
  64: import javax.accessibility.AccessibleRole;
  65: import javax.accessibility.AccessibleSelection;
  66: import javax.accessibility.AccessibleState;
  67: import javax.accessibility.AccessibleStateSet;
  68: import javax.accessibility.AccessibleTable;
  69: import javax.accessibility.AccessibleTableModelChange;
  70: import javax.swing.event.CellEditorListener;
  71: import javax.swing.event.ChangeEvent;
  72: import javax.swing.event.ListSelectionEvent;
  73: import javax.swing.event.ListSelectionListener;
  74: import javax.swing.event.TableColumnModelEvent;
  75: import javax.swing.event.TableColumnModelListener;
  76: import javax.swing.event.TableModelEvent;
  77: import javax.swing.event.TableModelListener;
  78: import javax.swing.plaf.TableUI;
  79: import javax.swing.table.DefaultTableCellRenderer;
  80: import javax.swing.table.DefaultTableColumnModel;
  81: import javax.swing.table.DefaultTableModel;
  82: import javax.swing.table.JTableHeader;
  83: import javax.swing.table.TableCellEditor;
  84: import javax.swing.table.TableCellRenderer;
  85: import javax.swing.table.TableColumn;
  86: import javax.swing.table.TableColumnModel;
  87: import javax.swing.table.TableModel;
  88: 
  89: /**
  90:  * The table component, displaying information, organized in rows and columns.
  91:  * The table can be placed in the scroll bar and have the optional header
  92:  * that is always visible. Cell values may be editable after double clicking
  93:  * on the cell. Cell columns may have various data types, that are 
  94:  * displayed and edited by the different renderers and editors. It is possible
  95:  * to set different column width. The columns are also resizeable by 
  96:  * dragging the column boundary in the header.
  97:  */
  98: public class JTable
  99:   extends JComponent
 100:   implements TableModelListener, Scrollable, TableColumnModelListener,
 101:              ListSelectionListener, CellEditorListener, Accessible
 102: {
 103:   /**
 104:    * Provides accessibility support for <code>JTable</code>.
 105:    *
 106:    * @author Roman Kennke (kennke@aicas.com)
 107:    */
 108:   protected class AccessibleJTable
 109:     extends AccessibleJComponent
 110:     implements AccessibleSelection, ListSelectionListener, TableModelListener,
 111:     TableColumnModelListener, CellEditorListener, PropertyChangeListener,
 112:     AccessibleExtendedTable
 113:   {
 114: 
 115:     /**
 116:      * Provides accessibility support for table cells.
 117:      *
 118:      * @author Roman Kennke (kennke@aicas.com)
 119:      */
 120:     protected class AccessibleJTableCell
 121:       extends AccessibleContext
 122:       implements Accessible, AccessibleComponent
 123:     {
 124: 
 125:       /**
 126:        * The table of this cell.
 127:        */
 128:       private JTable table;
 129: 
 130:       /**
 131:        * The row index of this cell.
 132:        */
 133:       private int row;
 134: 
 135:       /**
 136:        * The column index of this cell.
 137:        */
 138:       private int column;
 139: 
 140:       /**
 141:        * The index of this cell inside the AccessibleJTable parent.
 142:        */
 143:       private int index;
 144: 
 145:       /**
 146:        * Creates a new <code>AccessibleJTableCell</code>.
 147:        *
 148:        * @param t the table
 149:        * @param r the row
 150:        * @param c the column
 151:        * @param i the index of this cell inside the accessible table parent
 152:        */
 153:       public AccessibleJTableCell(JTable t, int r, int c, int i)
 154:       {
 155:         table = t;
 156:         row = r;
 157:         column = c;
 158:         index = i;
 159:       }
 160: 
 161:       /**
 162:        * Returns the accessible row for the table cell.
 163:        *
 164:        * @return the accessible row for the table cell
 165:        */
 166:       public AccessibleRole getAccessibleRole()
 167:       {
 168:         // TODO: What is the role of the table cell?
 169:         // Seems like the RI returns UNKNOWN here for 'normal' cells, might
 170:         // be different for special renderers though (not tested yet).
 171:         return AccessibleRole.UNKNOWN;
 172:       }
 173: 
 174:       /**
 175:        * Returns the accessible state set of this accessible table cell.
 176:        *
 177:        * @return the accessible state set of this accessible table cell
 178:        */
 179:       public AccessibleStateSet getAccessibleStateSet()
 180:       {
 181:         AccessibleStateSet state = new AccessibleStateSet();
 182: 
 183:         // Figure out the SHOWING state.
 184:         Rectangle visibleRect = getVisibleRect();
 185:         Rectangle cellRect = getCellRect(row, column, false);
 186:         if (visibleRect.intersects(cellRect))
 187:           state.add(AccessibleState.SHOWING);
 188: 
 189:         // Figure out SELECTED state.
 190:         if (isCellSelected(row, column))
 191:           state.add(AccessibleState.SELECTED);
 192: 
 193:         // Figure out ACTIVE state.
 194:         if (row == getSelectedRow() && column == getSelectedColumn())
 195:           state.add(AccessibleState.ACTIVE);
 196: 
 197:         // TRANSIENT seems to be always set in the RI.
 198:         state.add(AccessibleState.TRANSIENT);
 199: 
 200:         // TODO: Any other state to handle here?
 201:         return state;
 202:       }
 203: 
 204:       /**
 205:        * Returns the index of this cell in the parent object.
 206:        *
 207:        * @return the index of this cell in the parent object
 208:        */
 209:       public int getAccessibleIndexInParent()
 210:       {
 211:         return index;
 212:       }
 213: 
 214:       /**
 215:        * Returns the number of children of this object. Table cells cannot have
 216:        * children, so we return <code>0</code> here.
 217:        *
 218:        * @return <code>0</code>
 219:        */
 220:       public int getAccessibleChildrenCount()
 221:       {
 222:         return 0;
 223:       }
 224: 
 225:       /**
 226:        * Returns the accessible child at index <code>i</code>. Table cells
 227:        * don't have children, so we return <code>null</code> here.
 228:        *
 229:        * @return <code>null</code>
 230:        */
 231:       public Accessible getAccessibleChild(int i)
 232:       {
 233:         return null;
 234:       }
 235: 
 236:       /**
 237:        * Returns the locale setting for this accessible table cell.
 238:        *
 239:        * @return the locale setting for this accessible table cell
 240:        */
 241:       public Locale getLocale()
 242:       {
 243:         // TODO: For now, we return english here. This must be fixed as soon
 244:         // as we have a localized Swing.
 245:         return Locale.ENGLISH;
 246:       }
 247: 
 248:       /**
 249:        * Returns the accessible context of this table cell. Since accessible
 250:        * table cells are their own accessible context, we return
 251:        * <code>this</code>.
 252:        *
 253:        * @return the accessible context of this table cell
 254:        */
 255:       public AccessibleContext getAccessibleContext()
 256:       {
 257:         return this;
 258:       }
 259: 
 260:       /**
 261:        * Returns the background color of this cell.
 262:        *
 263:        * @return the background color of this cell
 264:        */
 265:       public Color getBackground()
 266:       {
 267:         return table.getBackground();
 268:       }
 269: 
 270:       /**
 271:        * Sets the background of the cell. Since table cells cannot have
 272:        * individual background colors, this method does nothing. Set the
 273:        * background directly on the table instead.
 274:        * 
 275:        * @param color not used
 276:        */
 277:       public void setBackground(Color color)
 278:       {
 279:         // This method does nothing. See API comments.
 280:       }
 281: 
 282:       /**
 283:        * Returns the foreground color of the table cell.
 284:        *
 285:        * @return the foreground color of the table cell
 286:        */
 287:       public Color getForeground()
 288:       {
 289:         return table.getForeground();
 290:       }
 291: 
 292:       /**
 293:        * Sets the foreground of the cell. Since table cells cannot have
 294:        * individual foreground colors, this method does nothing. Set the
 295:        * foreground directly on the table instead.
 296:        * 
 297:        * @param color not used
 298:        */
 299:       public void setForeground(Color color)
 300:       {
 301:         // This method does nothing. See API comments.
 302:       }
 303: 
 304:       /**
 305:        * Returns the cursor for this table cell.
 306:        *
 307:        * @return the cursor for this table cell
 308:        */
 309:       public Cursor getCursor()
 310:       {
 311:         return table.getCursor();
 312:       }
 313: 
 314:       /**
 315:        * Sets the cursor of the cell. Since table cells cannot have
 316:        * individual cursors, this method does nothing. Set the
 317:        * cursor directly on the table instead.
 318:        * 
 319:        * @param cursor not used
 320:        */
 321:       public void setCursor(Cursor cursor)
 322:       {
 323:         // This method does nothing. See API comments.
 324:       }
 325: 
 326:       /**
 327:        * Returns the font of the table cell.
 328:        *
 329:        * @return the font of the table cell
 330:        */
 331:       public Font getFont()
 332:       {
 333:         return table.getFont();
 334:       }
 335: 
 336:       /**
 337:        * Sets the font of the cell. Since table cells cannot have
 338:        * individual fonts, this method does nothing. Set the
 339:        * font directly on the table instead.
 340:        * 
 341:        * @param font not used
 342:        */
 343:       public void setFont(Font font)
 344:       {
 345:         // This method does nothing. See API comments.
 346:       }
 347: 
 348:       /**
 349:        * Returns the font metrics for a specified font.
 350:        *
 351:        * @param font the font for which we return the metrics
 352:        *
 353:        * @return the font metrics for a specified font
 354:        */
 355:       public FontMetrics getFontMetrics(Font font)
 356:       {
 357:         return table.getFontMetrics(font);
 358:       }
 359: 
 360:       /**
 361:        * Returns <code>true</code> if this table cell is enabled,
 362:        * <code>false</code> otherwise.
 363:        *
 364:        * @return <code>true</code> if this table cell is enabled,
 365:        *         <code>false</code> otherwise
 366:        */
 367:       public boolean isEnabled()
 368:       {
 369:         return table.isEnabled();
 370:       }
 371: 
 372:       /**
 373:        * Table cells cannot be disabled or enabled individually, so this method
 374:        * does nothing. Set the enabled flag on the table itself.
 375:        *
 376:        * @param b not used here
 377:        */
 378:       public void setEnabled(boolean b)
 379:       {
 380:         // This method does nothing. See API comments.
 381:       }
 382: 
 383:       /**
 384:        * Returns <code>true</code> if this cell is visible, <code>false</code>
 385:        * otherwise.
 386:        *
 387:        * @return <code>true</code> if this cell is visible, <code>false</code>
 388:        *         otherwise
 389:        */
 390:       public boolean isVisible()
 391:       {
 392:         return table.isVisible();
 393:       }
 394: 
 395:       /**
 396:        * The visibility cannot be set on individual table cells, so this method
 397:        * does nothing. Set the visibility on the table itself.
 398:        *
 399:        * @param b not used
 400:        */
 401:       public void setVisible(boolean b)
 402:       {
 403:         // This method does nothing. See API comments.
 404:       }
 405: 
 406:       /**
 407:        * Returns <code>true</code> if this table cell is currently showing on
 408:        * screen.
 409:        *
 410:        * @return <code>true</code> if this table cell is currently showing on
 411:        *         screen
 412:        */
 413:       public boolean isShowing()
 414:       {
 415:         return table.isShowing();
 416:       }
 417: 
 418:       /**
 419:        * Returns <code>true</code> if this table cell contains the location
 420:        * at <code>point</code>, <code>false</code> otherwise.
 421:        * <code>point</code> is interpreted as relative to the coordinate system
 422:        * of the table cell.
 423:        *
 424:        * @return <code>true</code> if this table cell contains the location
 425:        *         at <code>point</code>, <code>false</code> otherwise
 426:        */
 427:       public boolean contains(Point point)
 428:       {
 429:         Rectangle cellRect = table.getCellRect(row, column, true);
 430:         cellRect.x = 0;
 431:         cellRect.y = 0;
 432:         return cellRect.contains(point);
 433:       }
 434: 
 435:       /**
 436:        * Returns the screen location of the table cell.
 437:        *
 438:        * @return the screen location of the table cell
 439:        */
 440:       public Point getLocationOnScreen()
 441:       {
 442:         Point tableLoc = table.getLocationOnScreen();
 443:         Rectangle cellRect = table.getCellRect(row, column, true);
 444:         tableLoc.x += cellRect.x;
 445:         tableLoc.y += cellRect.y;
 446:         return tableLoc;
 447:       }
 448: 
 449:       /**
 450:        * Returns the location of this cell relative to the table's bounds.
 451:        *
 452:        * @return the location of this cell relative to the table's bounds
 453:        */
 454:       public Point getLocation()
 455:       {
 456:         Rectangle cellRect = table.getCellRect(row, column, true);
 457:         return new Point(cellRect.x, cellRect.y);
 458:       }
 459: 
 460:       /**
 461:        * The location of the table cells cannot be manipulated directly, so
 462:        * this method does nothing.
 463:        *
 464:        * @param point not used
 465:        */
 466:       public void setLocation(Point point)
 467:       {
 468:         // This method does nothing. See API comments.
 469:       }
 470: 
 471:       /**
 472:        * Returns the bounds of the cell relative to its table.
 473:        *
 474:        * @return the bounds of the cell relative to its table
 475:        */
 476:       public Rectangle getBounds()
 477:       {
 478:         return table.getCellRect(row, column, true);
 479:       }
 480: 
 481:       /**
 482:        * The bounds of the table cells cannot be manipulated directly, so
 483:        * this method does nothing.
 484:        *
 485:        * @param rectangle not used
 486:        */
 487:       public void setBounds(Rectangle rectangle)
 488:       {
 489:         // This method does nothing. See API comments.
 490:       }
 491: 
 492:       /**
 493:        * Returns the size of the table cell.
 494:        *
 495:        * @return the size of the table cell
 496:        */
 497:       public Dimension getSize()
 498:       {
 499:         Rectangle cellRect = table.getCellRect(row, column, true);
 500:         return new Dimension(cellRect.width, cellRect.height);
 501:       }
 502: 
 503:       /**
 504:        * The size cannot be set on table cells directly, so this method does
 505:        * nothing.
 506:        *
 507:        * @param dimension not used
 508:        */
 509:       public void setSize(Dimension dimension)
 510:       {
 511:         // This method does nothing. See API comments.
 512:       }
 513: 
 514:       /**
 515:        * Table cells have no children, so we return <code>null</code> here.
 516:        *
 517:        * @return <code>null</code>
 518:        */
 519:       public Accessible getAccessibleAt(Point point)
 520:       {
 521:         return null;
 522:       }
 523: 
 524:       /**
 525:        * Returns <code>true</code> if this table cell is focus traversable,
 526:        * <code>false</code> otherwise.
 527:        *
 528:        * @return <code>true</code> if this table cell is focus traversable,
 529:        *         <code>false</code> otherwise
 530:        */
 531:       public boolean isFocusTraversable()
 532:       {
 533:         return table.isFocusable();
 534:       }
 535: 
 536:       /**
 537:        * Requests that this table cell gets the keyboard focus.
 538:        */
 539:       public void requestFocus()
 540:       {
 541:         // We first set the selection models' lead selection to this cell.
 542:         table.getColumnModel().getSelectionModel()
 543:         .setLeadSelectionIndex(column);
 544:         table.getSelectionModel().setLeadSelectionIndex(row);
 545:         // Now we request that the table receives focus.
 546:         table.requestFocus();
 547:       }
 548: 
 549:       /**
 550:        * Adds a focus listener to this cell. The focus listener is really
 551:        * added to the table, so there is no way to find out when an individual
 552:        * cell changes the focus.
 553:        *
 554:        * @param listener the focus listener to add
 555:        */
 556:       public void addFocusListener(FocusListener listener)
 557:       {
 558:         table.addFocusListener(listener);
 559:       }
 560: 
 561:       /**
 562:        * Removes a focus listener from the cell. The focus listener is really
 563:        * removed from the table.
 564:        *
 565:        * @param listener the listener to remove
 566:        */
 567:       public void removeFocusListener(FocusListener listener)
 568:       {
 569:         table.removeFocusListener(listener);
 570:       }
 571:         
 572:     }
 573: 
 574:     protected class AccessibleJTableModelChange
 575:       implements AccessibleTableModelChange
 576:     {
 577:       protected int type;
 578:       protected int firstRow;
 579:       protected int lastRow;
 580:       protected int firstColumn;
 581:       protected int lastColumn;
 582: 
 583:       protected AccessibleJTableModelChange(int type, int firstRow,
 584:                                             int lastRow, int firstColumn,
 585:                                             int lastColumn)
 586:       {
 587:         this.type = type;
 588:         this.firstRow = firstRow;
 589:         this.lastRow = lastRow;
 590:         this.firstColumn = firstColumn;
 591:         this.lastColumn = lastColumn;
 592:       }
 593: 
 594:       public int getType()
 595:       {
 596:         return type;
 597:       }
 598: 
 599:       public int getFirstRow()
 600:       {
 601:         return firstRow;
 602:       }
 603: 
 604:       public int getLastRow()
 605:       {
 606:         return lastRow;
 607:       }
 608: 
 609:       public int getFirstColumn()
 610:       {
 611:         return firstColumn;
 612:       }
 613: 
 614:       public int getLastColumn()
 615:       {
 616:         return lastColumn;
 617:       }
 618:     }
 619: 
 620:     /**
 621:      * The RI returns an instance with this name in
 622:      * {@link #getAccessibleColumnHeader()}, this makes sense, so we do the
 623:      * same.
 624:      */
 625:     private class AccessibleTableHeader
 626:       implements AccessibleTable
 627:     {
 628: 
 629:       /**
 630:        * The JTableHeader wrapped by this class.
 631:        */
 632:       private JTableHeader header;
 633: 
 634:       /**
 635:        * Creates a new instance.
 636:        *
 637:        * @param h the JTableHeader to wrap
 638:        */
 639:       private AccessibleTableHeader(JTableHeader h)
 640:       {
 641:         header = h;
 642:       }
 643: 
 644:       /**
 645:        * Returns the caption for the table header.
 646:        *
 647:        * @return the caption for the table header
 648:        */
 649:       public Accessible getAccessibleCaption()
 650:       {
 651:         // The RI seems to always return null here, so do we.
 652:         return null;
 653:       }
 654: 
 655:       /**
 656:        * Sets the caption for the table header.
 657:        *
 658:        * @param caption the caption to set
 659:        */
 660:       public void setAccessibleCaption(Accessible caption)
 661:       {
 662:         // This seems to be a no-op in the RI, so we do the same.
 663:       }
 664: 
 665:       /**
 666:        * Returns the caption for the table header.
 667:        *
 668:        * @return the caption for the table header
 669:        */
 670:       public Accessible getAccessibleSummary()
 671:       {
 672:         // The RI seems to always return null here, so do we.
 673:         return null;
 674:       }
 675: 
 676:       /**
 677:        * Sets the summary for the table header.
 678:        *
 679:        * @param summary the caption to set
 680:        */
 681:       public void setAccessibleSummary(Accessible summary)
 682:       {
 683:         // This seems to be a no-op in the RI, so we do the same.
 684:       }
 685: 
 686:       /**
 687:        * Returns the number of rows, which is always 1 for the table header.
 688:        *
 689:        * @return the number of rows
 690:        */
 691:       public int getAccessibleRowCount()
 692:       {
 693:         return 1;
 694:       }
 695: 
 696:       /**
 697:        * Returns the number of columns in the table header.
 698:        *
 699:        * @return the number of columns in the table header
 700:        */
 701:       public int getAccessibleColumnCount()
 702:       {
 703:         return header.getColumnModel().getColumnCount();
 704:       }
 705: 
 706:       /**
 707:        * Returns the accessible child at the specified row and column.
 708:        * The row number is ignored here, and we return an
 709:        * AccessibleJTableHeaderCell here with the renderer component as
 710:        * component.
 711:        *
 712:        * @param r the row number
 713:        * @param c the column number
 714:        *
 715:        * @return the accessible child at the specified row and column
 716:        */
 717:       public Accessible getAccessibleAt(int r, int c)
 718:       {
 719:         TableColumn column = header.getColumnModel().getColumn(c);
 720:         TableCellRenderer rend = column.getHeaderRenderer();
 721:         if (rend == null)
 722:           rend = header.getDefaultRenderer();
 723:         Component comp =
 724:           rend.getTableCellRendererComponent(header.getTable(),
 725:                                              column.getHeaderValue(), false,
 726:                                              false, -1, c);
 727:         return new AccessibleJTableHeaderCell(header, comp, r, c);
 728:       }
 729: 
 730:       public int getAccessibleRowExtentAt(int r, int c)
 731:       {
 732:         // TODO Auto-generated method stub
 733:         return 0;
 734:       }
 735: 
 736:       public int getAccessibleColumnExtentAt(int r, int c)
 737:       {
 738:         // TODO Auto-generated method stub
 739:         return 0;
 740:       }
 741: 
 742:       public AccessibleTable getAccessibleRowHeader()
 743:       {
 744:         // TODO Auto-generated method stub
 745:         return null;
 746:       }
 747: 
 748:       public void setAccessibleRowHeader(AccessibleTable header)
 749:       {
 750:         // TODO Auto-generated method stub
 751:         
 752:       }
 753: 
 754:       public AccessibleTable getAccessibleColumnHeader()
 755:       {
 756:         // TODO Auto-generated method stub
 757:         return null;
 758:       }
 759: 
 760:       public void setAccessibleColumnHeader(AccessibleTable header)
 761:       {
 762:         // TODO Auto-generated method stub
 763:         
 764:       }
 765: 
 766:       public Accessible getAccessibleRowDescription(int r)
 767:       {
 768:         // TODO Auto-generated method stub
 769:         return null;
 770:       }
 771: 
 772:       public void setAccessibleRowDescription(int r, Accessible description)
 773:       {
 774:         // TODO Auto-generated method stub
 775:         
 776:       }
 777: 
 778:       public Accessible getAccessibleColumnDescription(int c)
 779:       {
 780:         // TODO Auto-generated method stub
 781:         return null;
 782:       }
 783: 
 784:       public void setAccessibleColumnDescription(int c, Accessible description)
 785:       {
 786:         // TODO Auto-generated method stub
 787:         
 788:       }
 789: 
 790:       public boolean isAccessibleSelected(int r, int c)
 791:       {
 792:         // TODO Auto-generated method stub
 793:         return false;
 794:       }
 795: 
 796:       public boolean isAccessibleRowSelected(int r)
 797:       {
 798:         // TODO Auto-generated method stub
 799:         return false;
 800:       }
 801: 
 802:       public boolean isAccessibleColumnSelected(int c)
 803:       {
 804:         // TODO Auto-generated method stub
 805:         return false;
 806:       }
 807: 
 808:       public int[] getSelectedAccessibleRows()
 809:       {
 810:         // TODO Auto-generated method stub
 811:         return null;
 812:       }
 813: 
 814:       public int[] getSelectedAccessibleColumns()
 815:       {
 816:         // TODO Auto-generated method stub
 817:         return null;
 818:       }
 819:         
 820:     }
 821: 
 822:     /**
 823:      * The RI returns an instance of such class for table header cells. This
 824:      * makes sense so I added this class. This still needs to be fully
 825:      * implemented, I just don't feel motivated enough to do so just now.
 826:      */
 827:     private class AccessibleJTableHeaderCell
 828:       extends AccessibleContext
 829:       implements Accessible, AccessibleComponent
 830:     {
 831: 
 832:       JTableHeader header;
 833:       
 834:       int columnIndex;
 835:       
 836:       /**
 837:        * 
 838:        * @param h  the table header.
 839:        * @param comp
 840:        * @param r
 841:        * @param c  the column index.
 842:        */
 843:       private AccessibleJTableHeaderCell(JTableHeader h, Component comp, int r,
 844:                                          int c)
 845:       {
 846:         header = h;
 847:         columnIndex = c;
 848:       }
 849: 
 850:       /**
 851:        * Returns the header renderer.
 852:        * 
 853:        * @return The header renderer.
 854:        */
 855:       Component getColumnHeaderRenderer()
 856:       {
 857:         TableColumn tc = header.getColumnModel().getColumn(columnIndex);
 858:         TableCellRenderer r = tc.getHeaderRenderer();
 859:         if (r == null)
 860:           r = header.getDefaultRenderer();
 861:         return r.getTableCellRendererComponent(header.getTable(), 
 862:             tc.getHeaderValue(), false, false, -1, columnIndex);
 863:       }
 864:       
 865:       /**
 866:        * Returns the accessible role for the table header cell.
 867:        * 
 868:        * @return The accessible role.
 869:        */
 870:       public AccessibleRole getAccessibleRole()
 871:       {
 872:         Component renderer = getColumnHeaderRenderer();
 873:         if (renderer instanceof Accessible)
 874:           {
 875:             Accessible ac = (Accessible) renderer;
 876:             return ac.getAccessibleContext().getAccessibleRole();
 877:           }
 878:         return null;
 879:       }
 880: 
 881:       public AccessibleStateSet getAccessibleStateSet()
 882:       {
 883:         // TODO Auto-generated method stub
 884:         return null;
 885:       }
 886: 
 887:       public int getAccessibleIndexInParent()
 888:       {
 889:         // TODO Auto-generated method stub
 890:         return 0;
 891:       }
 892: 
 893:       public int getAccessibleChildrenCount()
 894:       {
 895:         // TODO Auto-generated method stub
 896:         return 0;
 897:       }
 898: 
 899:       public Accessible getAccessibleChild(int i)
 900:       {
 901:         // TODO Auto-generated method stub
 902:         return null;
 903:       }
 904: 
 905:       public Locale getLocale()
 906:       {
 907:         // TODO Auto-generated method stub
 908:         return null;
 909:       }
 910: 
 911:       /**
 912:        * Returns the accessible context.
 913:        * 
 914:        * @return <code>this</code>.
 915:        */
 916:       public AccessibleContext getAccessibleContext()
 917:       {
 918:         return this;
 919:       }
 920: 
 921:       public Color getBackground()
 922:       {
 923:         // TODO Auto-generated method stub
 924:         return null;
 925:       }
 926: 
 927:       public void setBackground(Color color)
 928:       {
 929:         // TODO Auto-generated method stub
 930:         
 931:       }
 932: 
 933:       public Color getForeground()
 934:       {
 935:         // TODO Auto-generated method stub
 936:         return null;
 937:       }
 938: 
 939:       public void setForeground(Color color)
 940:       {
 941:         // TODO Auto-generated method stub
 942:         
 943:       }
 944: 
 945:       public Cursor getCursor()
 946:       {
 947:         // TODO Auto-generated method stub
 948:         return null;
 949:       }
 950: 
 951:       public void setCursor(Cursor cursor)
 952:       {
 953:         // TODO Auto-generated method stub
 954:         
 955:       }
 956: 
 957:       public Font getFont()
 958:       {
 959:         // TODO Auto-generated method stub
 960:         return null;
 961:       }
 962: 
 963:       public void setFont(Font font)
 964:       {
 965:         // TODO Auto-generated method stub
 966:         
 967:       }
 968: 
 969:       public FontMetrics getFontMetrics(Font font)
 970:       {
 971:         // TODO Auto-generated method stub
 972: