Обход фокуса внутри компонентов в редакторе ячеек

Я пытаюсь упростить редактирование таблицы, в которой используется пользовательский компонент для отображения информации. Каждая ячейка имеет 3 текста данных.

Я хочу:

  • если ячейка получает фокус, начните редактировать 1-е значение.
  • при редактировании 1-го значения нажмите [TAB], затем перейдите к редактированию 2-го значения (не переходите к следующей ячейке)
  • если я нажму [TAB] в 3-м значении, затем перейду к редактированию следующей ячейки (введя значение 1sr)

Я не искал на форумах и не нашел этого случая, этой проблемы ... все еще читаю, чтобы изучить Swing

Заранее спасибо за ваши ответы, это мой код:

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);

        }

    }
}

person Community    schedule 09.02.2010    source источник


Ответы (1)


В настоящее время ваш JTable обрабатывает ввод с клавиатуры, используя InputMap из UIManager.get("Table.ancestorInputMap"). В настоящее время вкладка сопоставлена ​​со строкой "selectNextColumnCell", которая сопоставляется с действием в ActionMap JTable, которое перемещает вас к следующей ячейке.

Вы можете сделать следующее:

  1. Создайте действие, метод actionPerformed которого выполняет политику обхода, которая вам нужна.

  2. В ActionMap поместите «someStringThatDescribesYourAction» в качестве ключа и ваше действие из 1 в качестве значения.

  3. В InputMap поместите KeyStroke.getKeyStroke("TAB") в качестве ключа и строку из 2 в качестве значения. Это заменит текущее действие, которое независимо переместит вас в следующую ячейку.

person lins314159    schedule 10.02.2010