有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JTable密钥侦听器

我需要我的JTable来验证给定行的数据,并将column1的组件更改为JButton,标记为“保存”(准备记录保存),如果验证确定数据正常。我需要对每次击键做出反应

无论我做了多少尝试,用户似乎都必须关闭单元格编辑器(通过单击其他位置或按Enter键),然后才能计算数据

你知道有没有一种方法可以让按键监听器(或其他方法)提供即时反馈,而不是强制执行这个额外的按键/鼠标移动

使用DefaultCellEditor进行数据评估仍然需要额外的击键,而键绑定(显然不需要)似乎只需要对特定的键做出反应

有没有一种方法可以提供一个监听器,该监听器可以对编辑器中的每个击键立即做出反应

m0skit0对问题的跟进

问:我试过什么

答:我有一个名为ButtonColumn的类,根据Rob Camick改编,它实现了TableCellRenderer

这将验证行数据,如果验证成功,则将单元格呈现为标记为“保存”的JButton,否则将返回带有纯文本标签“新建…”(红色字体)的DefaultRenderer组件

我有另一个实现KeyListener的类,它在用户每次击键时重新绘制表,从而执行SaveButtonRowFormatter验证和呈现(如上所述)

此操作仅在的单元编辑器关闭后有效。这就是问题所在:用户必须关闭编辑器才能呈现表格并显示“保存”按钮。这是不直观的,因为没有明显的原因说明用户在确定已成功填写记录后会进行任何按键操作。此时,如果没有任何保存按钮,它们将被卡住


共 (2) 个答案

  1. # 1 楼答案

    Is there a way to provide a listener that will react instantly to each keystroke in the editor?

    将DocumentListener添加到编辑器的编辑器组件

    DefaultCellEditor dce = (DefaultCellEditor)table.getDefaultEditor(Object.class);
    JTextField textField = (JTextField)dce.getComponent();
    textField.getDocument().addDocumentListener(...);
    

    有关更多信息,请阅读Swing教程中关于How to Write a Document Listener的部分

  2. # 2 楼答案

    最简单的方法是使用:

    table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
    

    否则,您可以执行以下操作:

    在按钮的ActionListener中,只需执行if(table.getCellEditor()!=null) table.getCellEditor().stopCellEditing();

    请参见此示例,先打印模型,然后再打印

    要尝试它,只需开始编辑任何单元格,然后按“保存”(不单击任何其他位置或取消编辑状态),您将看到控制台中的输出不同(第二个输出考虑到您最近所做的修改)

    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Vector;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingUtilities;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableModel;
    
    public class TestEditableTable {
    
        protected void initUI() {
            JFrame frame = new JFrame(TestEditableTable.class.getSimpleName());
            Vector<Vector<String>> data = new Vector<Vector<String>>();
            for (int i = 0; i < 2; i++) {
                Vector<String> row = new Vector<String>();
                for (int j = 0; j < 5; j++) {
                    row.add("Cell " + i + "," + j);
                }
                data.add(row);
            }
            Vector<String> columns = new Vector<String>();
            for (int j = 0; j < 5; j++) {
                columns.add("Column " + j);
            }
            final TableModel model = new DefaultTableModel(data, columns);
            final JTable table = new JTable(model);
            frame.add(new JScrollPane(table), BorderLayout.CENTER);
            JButton save = new JButton("Save");
            save.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    printDataModel(model);
                    if (table.getCellEditor() != null) {
                        table.getCellEditor().stopCellEditing();
                    }
                    printDataModel(model);
                }
    
                private void printDataModel(final TableModel model) {
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < model.getRowCount(); i++) {
                        for (int j = 0; j < model.getColumnCount(); j++) {
                            sb.append(model.getValueAt(i, j)).append(' ');
                        }
                        sb.append("\n");
                    }
                    System.out.println(sb);
                }
            });
            frame.add(save, BorderLayout.SOUTH);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new TestEditableTable().initUI();
                }
            });
        }
    }