单元格编辑器中组件内的焦点遍历

发布于 2024-08-21 00:40:06 字数 6442 浏览 6 评论 0原文

我正在尝试轻松编辑使用自定义组件来显示信息的表格。 每个 Cell 有 3 个数据文本。

我想要的是:

  • 如果单元格获得焦点,则开始编辑第一个值。
  • 编辑第一个值时,用户按 [TAB],然后去编辑第二个值(不要转到下一个单元格)
  • 如果我在第三个值中按 [TAB],然后去编辑下一个单元格(输入 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);

        }

    }
}

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

        }

    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

思慕 2024-08-28 00:40:06

目前,您的 JTable 使用 UIManager.get("Table.ancestorInputMap") 中的 InputMap 处理键盘输入。目前,该选项卡已映射到字符串“selectNextColumnCell”,该字符串映射到 JTable 的 ActionMap 中的一个操作,可将您移动到下一个单元格。

您可以执行以下操作:

  1. 创建一个 Action,其 actionPerformed 方法执行您所追求的遍历策略。

  2. 在 ActionMap 中,将“someStringThatDescribesYourAction”作为键,将 1 中的 Action 作为值。

  3. 在InputMap中,将KeyStroke.getKeyStroke("TAB")作为键,将2中的字符串作为值。这将替换当前的操作,从而将您移动到下一个单元格。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文