0

I am working on making the Arduino IDE fully accessible for people using access software. This means adding keyboard accessibility to two of the dialogs that currently do not work with access software under windows. The two dialogs are the Board Manager and the LibraryManager. If you want a real example of what I am posting you can get teh Arduino IDE on the Windows Store or download it on line. Just search for Arduino IDE and download the windows version. .

doing all that might be to much for most of you so I have created a more simple table that shows the same problem. If someone can help me understand how to add keyboard and focus access to the below Custom JTable and its custom column which is a JPanel I can work on fixing the Arduino IDE tables.

I understand that the Arduino IDE should probably be made into a better table but I have yet to figure out a cleaner way to do what they are doing with these tables so I am trying to make what they have accessible.

So below is my problem table. It has two rows and two columsn. The second column of each row is a panel of controls. I have borrowed this code from some other stack posts and modified it to fit my question. So if you think you have seen some of this code before that is why. The problem is the code works for a mouse. At least I think it does because I am blind and can not select the controls on the second column because they can not get keyboard focus.

So Can someone out there help me figure out how to get keyboard focus to move through this entire table. I have tried using focus listeners, keyboard listeners, Focus Traversal policies, property changes, and combinations between all of the above. I have taken out my terrible attempts. Swing really should work without having to do all this extra work but Java is what java is.

So if you are great at Java with swing please put away your mouse and run this code and see if you can make the buttons activate without the mouse. If you can and you can explain to me how to do it many blind users will be in your debt.

Note that you should be able to Shift+Control+tab tot he table if the table is not the only control. On my sample it is. Then you should be able to arrow through the rows and columns and tab and shift+tab through the controls on the JPanel.

You can get the zip group of these files if you don't want to put this all together yourself at this dropbox link: https://www.dropbox.com/s/h4bdfu1mlo0jsvr/TableAccessTest.zip?dl=0

Here is the files. Each class has a comment with the file name before it. Again get the zip if you don't want to play block and copy.

//TableAccessTest.java
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;

public class TableAccessTest extends JPanel
{

  TableModel customRendererEditorTableModel = new TableModel();
  JTable table;

  public TableAccessTest()
  {
    setLayout(new BorderLayout());

    table = new JTable(customRendererEditorTableModel);
    table.setPreferredScrollableViewportSize(new Dimension(500, 600));
    table.setRowSelectionAllowed(false);
    table.setRowHeight(300);
    table.getColumn("Custom JPanel").setCellRenderer(new CustomJPanelRenderer());
    table.getColumn("Custom JPanel").setCellEditor(new CustomJPanelEditor());

    JScrollPane scrollPane = new JScrollPane(table);
    add(scrollPane);

  }

  private static void createAndShowGUI()
  {
    JFrame frame = new JFrame("Custom JPanel");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JComponent newContentPane = new TableAccessTest();
    newContentPane.setOpaque(true);
    frame.setContentPane(newContentPane);
    frame.pack();
    frame.setVisible(true);
  }

  public static void main(String[] args)
  {
    javax.swing.SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
    createAndShowGUI();
      }
    });
  }
}

//CustomJPanel.java 

import java.awt.*;
import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.*;

public class CustomJPanel extends JPanel
{

  JPanel colorPanel = new JPanel(new BorderLayout());
  JButton jButton = new JButton("Change Color");
  JSlider jSlider = new JSlider(JSlider.VERTICAL);
JTextField jTextField = new JTextField("");


  public CustomJPanel()
  {
    jButton.setOpaque(true);
    jButton.setFocusable(true);
    jTextField.setEditable(false);
    jTextField.setFocusable(true);
    setFocusable(true);
    jButton.addActionListener(new ActionListener()
    {

      @Override
      public void actionPerformed(ActionEvent e)
{
    Random randomGenerator = new Random();
    int randomInt = randomGenerator.nextInt(4);

    switch (randomInt)
    {
      case (0):
        colorPanel.setBackground(Color.BLUE);
        jTextField.setText("blue");
        break;
      case (1):
        colorPanel.setBackground(Color.BLACK);
                jTextField.setText("black");
        break;
      case (2):
        colorPanel.setBackground(Color.CYAN);
                jTextField.setText("cyan");
        break;
      default:
        colorPanel.setBackground(Color.GREEN);
                jTextField.setText("green");
        break;
    }
      }
    });
    jSlider.setOpaque(true);
    setLayout(new BorderLayout());
    add(colorPanel, BorderLayout.CENTER);
    add(jButton, BorderLayout.SOUTH);
        add(jTextField, BorderLayout.NORTH);
    add(jSlider, BorderLayout.EAST);
  }
}






//TableModel.java 
import javax.swing.table.AbstractTableModel;

public class TableModel extends AbstractTableModel
{

  private String[] columnNames =
  {
    "First Column",
    "Custom JPanel",
  };
  private Object[][] data =
  {
    {"Foo", new CustomJPanel()},
    {"Bar", new CustomJPanel()}
  };

  public int getColumnCount()
  {
    return columnNames.length;
  }

  public int getRowCount()
  {
    return data.length;
  }

  public String getColumnName(int col)
  {
    return columnNames[col];
  }

  public Object getValueAt(int row, int col)
  {
    return data[row][col];
  }

  public Class getColumnClass(int c)
  {
    return getValueAt(0, c).getClass();
  }

  public boolean isCellEditable(int row, int col)
  {
    return col >= 1;
  }

  public void setValueAt(Object value, int row, int col)
  {
    data[row][col] = value;
    fireTableCellUpdated(row, col);
  }

}


//CustomJPanelEditor.java 

import javax.swing.AbstractCellEditor;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;

public class CustomJPanelEditor extends AbstractCellEditor implements TableCellEditor
{
  CustomJPanel customJPanel;

  public CustomJPanelEditor()
  {
    customJPanel = new CustomJPanel();
  }

  @Override
  public java.awt.Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
  {
    customJPanel = (CustomJPanel) value;
    return customJPanel;
  }

  @Override  public Object getCellEditorValue()
  {
    return customJPanel;
  }
}


//CustomJPanelRenderer.java

import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

public class CustomJPanelRenderer implements TableCellRenderer
  {

    CustomJPanel rendererJPanel;

  public CustomJPanelRenderer()
  {
    rendererJPanel = new CustomJPanel();
  }


    @Override
    public java.awt.Component getTableCellRendererComponent(JTable table, Object value,
        boolean isSelected, boolean hasFocus, int row, int column) 
    {
      rendererJPanel = (CustomJPanel) value;
      return rendererJPanel;
    }
  }
  • A JTable is designed to contain a single data value in each cell. It is not designed to contain a panel of components with different values. From your example it looks like you are attempting to change the Color of the cell. I suggest you look at the section in the Swing tutorial on [Using Other Editors](https://docs.oracle.com/javase/tutorial/uiswing/components/table.html#editor). It will show you how to display the JColorChooser when you edit the cell. If you want to us a custom dialog instead then check out: https://stackoverflow.com/a/3591230/131872 for another example. – camickr Jan 15 '19 at 16:12
  • As I said above this is just a simplified table that has the same problem as the Arduino IDE Library and boards dialogs. I understand that this is not how the tables are designed to be used but this is how people are using them. Note I didn't even write the example code because I could just get the example code from other people that are doing this. So what I need is to know how to make keyboard focus work with the controls. Ignore the color it could be any control. Three buttons lets say. – Ken Perry Jan 16 '19 at 18:07

0 Answers0