views:

184

answers:

1

Hi, i´m trying to make easy edit to a table thas uses a custom component for displaying info. Each Cell hast 3 data texts.

What i want is:

  • if a cell gets focus, start editing the 1st value.
  • while editing the 1st value user press [TAB], then go editing the 2nd value (don´t go to the next cell)
  • if i press [TAB] in the 3rd value, then, go editing the next cell (entering the 1sr value)

I wass looking in forums an i didn´t find this case, this problem... still reading to learn Swing

Thanks in advance for your answers, this is my code:

public class PruebaTabla extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){

            public void run() {
                new PruebaTabla().setVisible(true);
            }});
    }
    public PruebaTabla(){

        JTable tabla = new JTable(); 

        tabla.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        tabla.setCellSelectionEnabled(true);
        tabla.setDefaultRenderer(ModelClass.class, new ModelClassCellRederer());
        tabla.setDefaultEditor(ModelClass.class, new ModelClasstroCellEditor());
        tabla.setRowHeight(30);

        CustomModel model = new CustomModel();
        model.setModel(new ModelClass[][]{
                                        {new ModelClass(), new ModelClass(), new ModelClass()},
                                        {new ModelClass(), new ModelClass(), new ModelClass()},
                                        {new ModelClass(), new ModelClass(), new ModelClass()}});
        tabla.setModel(model);


        getContentPane().add(new JScrollPane(tabla));
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(480,150);
        setLocationRelativeTo(null);

    }

    private class ModelClass {

        private String value1;
        private String value2;
        private String value3;
        public ModelClass(){
            setValue1("" + Math.round(Math.random() * 100));
            setValue2("" + Math.round(Math.random() * 100));
            setValue3("" + Math.round(Math.random() * 100));
        }
        public String getValue1() {
            return value1;
        }
        public void setValue1(String value1) {
            this.value1 = value1;
        }
        public String getValue2() {
            return value2;
        }
        public void setValue2(String value2) {
            this.value2 = value2;
        }
        public String getValue3() {
            return value3;
        }
        public void setValue3(String value3) {
            this.value3 = value3;
        }

    }

    private class CustomModel extends AbstractTableModel{

        ModelClass[][] model;
        String[] columnNames = new String[] {"Column1", "Column2", "Column3"};

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return ModelClass.class;
        }

        @Override
        public String getColumnName(int column) {
            return columnNames[column];
        }
        public int getColumnCount() {       
            return 3;
        }

        public int getRowCount() {
            return 3;
        }

        public Object getValueAt(int rowIndex, int columnIndex) {           
            return model[rowIndex][columnIndex];
        }

        public ModelClass[][] getModel() {
            return model;
        }

        public void setModel(ModelClass[][] model) {
            this.model = model;
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {          
            return true;
        }
    }

    private class ModelClassCellRederer implements TableCellRenderer {

        JPanel panel = new JPanel();
        private JLabel label1= new JLabel();
        private JLabel label2 = new JLabel();
        private JLabel label3 = new JLabel();

        ModelClassCellRederer(){
            panel.add(label1);
            panel.add(label2);
            panel.add(label3);
        }

        public Component getTableCellRendererComponent(JTable table,
                Object value, boolean isSelected, boolean hasFocus, int row,
                int column) {

             if (isSelected) {
                 panel.setBackground(table.getSelectionBackground());
                 panel.setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
             } else {
                 panel.setBackground(table.getBackground());
                 panel.setBorder(null);
             }

            ModelClass v = (ModelClass) value;
            label1.setText(v.getValue1());
            label2.setText(v.getValue2());
            label3.setText(v.getValue3());

            return panel;
        }

    }

    private class ModelClasstroCellEditor extends DefaultCellEditor {

        JPanel panel = new JPanel();
        private JTextField label1= new JTextField();
        private JTextField label2 = new JTextField();
        private JTextField label3 = new JTextField();
        ModelClass actual;

        public ModelClasstroCellEditor() {
            super(new JCheckBox());
            panel.add(label1);
            panel.add(label2);
            panel.add(label3);
            setClickCountToStart(1);
        }

        @Override
        public Component getTableCellEditorComponent(JTable table,
                Object value, boolean isSelected, int row, int column) {
            actual = (ModelClass) value;
            label1.setText(actual.getValue1());
            label2.setText(actual.getValue2());
            label3.setText(actual.getValue3());

            return panel;
        }

        @Override
        public Object getCellEditorValue() {
            if (actual != null){
                actual.setValue1(label1.getText());
                actual.setValue2(label2.getText());
                actual.setValue3(label3.getText());
            }
            return actual;
        }

        @Override
        public boolean isCellEditable(EventObject anEvent) {
             if (anEvent instanceof KeyEvent) {
                 final KeyEvent keyEvent = (KeyEvent) anEvent;

                 SwingUtilities.invokeLater(new Runnable() {

                    public void run() {
                       if (!Character.isIdentifierIgnorable(keyEvent.getKeyChar())) {
                           label1.setText("" + keyEvent.getKeyChar());
                       }
                       label1.setCaretPosition(label1.getText().length());
                       label1.requestFocusInWindow();
                    }
                 });
              }
              return super.isCellEditable(anEvent);

        }

    }
}
+1  A: 

Currently, your JTable handles keyboard input using an InputMap from UIManager.get("Table.ancestorInputMap"). This currently has tab mapped to the String "selectNextColumnCell", which maps to an Action in JTable's ActionMap that moves you to the next cell.

You can do the following:

  1. Create an Action whose actionPerformed method does the traversal policy that you're after.

  2. In the ActionMap, put "someStringThatDescribesYourAction" as the key, and your Action from 1 as the value.

  3. In the InputMap, put KeyStroke.getKeyStroke("TAB") as the key, and the String from 2 as the value. This will replace the current Action which moves you to the next cell regardless.

lins314159