1 Reply Latest reply: Dec 22, 2010 1:22 PM by user4547241 RSS

    Accessibilty: a ghost (at least for JTable)?

      Very recently (and incidentally just after a thread here) we got a support question about Accessibility in SwingX


      after playing a bit, I'm disgusted by both core behaviour and core code. In no particular order (every single bullet is a show-stopper)

      Break JTable method contracts

      AccessibleJTableContext (and/or) nested classes break table method guarantees:
      // the guarantee:
           * <b>Note:</b>
           * Throughout the table package, the internal implementations always
           * use this method to provide renderers so that this default behavior
           * can be safely overridden by a subclass.
          public TableCellRenderer getCellRenderer(int row, int column) {
      // the breakage (just one of many), here it's AccessibleTableCell
                   * Gets the table cell renderer component.
                   * @return the table cell renderer component if one exists;
                   * otherwise, returns <code>null</code>.
                   * @since 1.6
                  protected Component getCurrentComponent() {
                      TableColumn aColumn = getColumnModel().getColumn(column);
                      TableCellRenderer renderer = aColumn.getCellRenderer();
                      if (renderer == null) {
                          Class<?> columnClass = getColumnClass(column);
                          renderer = getDefaultRenderer(columnClass);
                      return renderer.getTableCellRendererComponent(
                                        JTable.this, null, false, false,
                                        row, column);
      EDT violation

      AccessBridge (and/or the accessible context implementations, didn't really track), access and configure table state off the EDT. To reproduce, simply add a check into the renderer of your choice, and get the culprit/s:
      // the check:
          public Component getTableCellRendererComponent(JTable table, Object value,
                  boolean isSelected, boolean hasFocus, int row, int column) {
              if (!SwingUtilities.isEventDispatchThread()) {
                  try {
                      throw new IllegalStateException("must be in EDT");
                  } catch (Exception e) {
      // the output:
      java.lang.IllegalStateException: must be in EDT
           at org.jdesktop.swingx.renderer.DefaultTableRenderer.getTableCellRendererComponent(DefaultTableRenderer.java:170)
           at javax.swing.JTable$AccessibleJTable.getAccessibleChild(JTable.java:7023)
           at com.sun.java.accessibility.AccessBridge.getActiveDescendent(AccessBridge.java:3845)
           at com.sun.java.accessibility.AccessBridge.run(Native Method)
           at java.lang.Thread.run(Thread.java:662)
      That's a deadly sin in any case, for swingx it produces visible artefacts in occasionally showing empty cells. As an aside: it feels fishy to use the renderer as accessibleComponent, it's never really part of the container hierarchy (except at the very moment of painting), so it's showing/displaying is false always.

      Confused by column moves

      to reproduce, select a cell (the content of the focused cell is read), then move columns around for a while: the focus sticks to the view column (outch.. that looks like a table/ColumnModel issue) the read content is ... unpredicatable.

      TableHeader unaccessible

      make it focusable, move the focus into the header: expected that the title is read - nothing happens

      Probably could go on ... will stop for now, as there's the non-zero probability that I missed something important ;)

      Comments, please?