java - 在保存到 JTable Cell 之前检查输入有效性

标签 java swing jtable

我想在每次更改 JTable 上的值时检查用户输入的有效性。我想到的方法类似于这个简化的示例代码:

public static void main(String[] args) {
    JFrame main = new JFrame();

    JTable table = new JTable(6, 4);
    table.setSize(300, 300);


    table.getModel().addTableModelListener((TableModelEvent e) -> {
            Object s = e.getSource();
            TableModel d = (TableModel) s;                    
            if(!checkValid(d.getValueAt(e.getFirstRow(), e.getColumn())))
            {
                d.setValueAt(" - ", e.getFirstRow(), e.getColumn());                    
            }

    });

    main.add(table);
    main.setSize(300,300);
    main.setLocationRelativeTo(null);
    main.setVisible(true);
    main.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}

如果表中发生更改,代码将检查输入,如果输入无效,代码将恢复为“-”。

但是,会出现错误,指出线程“AWT-EventQueue-0”中出现异常 java.lang.StackOverflowError

a.) 有人可以解释一下这个错误以及如何解决这个问题吗?

b.) 或者是否有更好的方法来实现监听器,在退出编辑模式或保存表格之前检查用户输入?

EDIT: I have tried implementing the CellEditorListener like the sample below:

table.getCellEditor().addCellEditorListener(new CellEditorListener() {
    public void editingStopped(ChangeEvent e)
    {

    }
    public void editingCanceled(ChangeEvent e)
    {

    }
});

这又引发了错误线程“main”java.lang.NullPointerException中的异常。关于 CellEditorListener 的文档不多,并且不太了解它的工作原理以及如何使用它。

最佳答案

根据相应栏目对应Java tutorials ,您可以覆盖 stopCellEditingDefaultCellEditor如果编辑器不应失去焦点,则返回 false ,否则返回 true 。这意味着我们可以使用它首先检查用户输入,然后根据用户的输入,如果他/她输入无效文本,则返回 false (如果他/她输入无效文本,则返回 true输入有效的)。

在下面的示例代码中,我使用了 JTextField,它允许用户输入他们想要的任何内容,然后检查用户在 stopCellEditing 中的输入是否为非空(由我的静态 checkValid 方法定义,但您显然可以根据需要更改它):

import java.awt.Toolkit;
import javax.swing.DefaultCellEditor;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;

public class Main {
    public static boolean checkValid(final String text) {
        return text != null && !text.trim().isEmpty(); //Your checks here...
    }

    public static class MyCellEditor extends DefaultCellEditor {
        public MyCellEditor() {
            super(new JTextField());
        }

        @Override
        public boolean stopCellEditing() {
            final JTextField field = (JTextField) getComponent();
            if (checkValid(field.getText())) {
                //field.setBackground(Color.WHITE);
                return super.stopCellEditing(); //Fires 'editing stopped' event and returns true.
            }
            Toolkit.getDefaultToolkit().beep();
            //field.setBackground(Color.ORANGE.darker());
            JOptionPane.showMessageDialog(field, "You must enter a non-empty value!", "Oups!", JOptionPane.ERROR_MESSAGE);
            return false;
        }
    }

    public static void main(final String[] args) {
        final JTable table = new JTable(new DefaultTableModel(10, 10));
        table.setDefaultEditor(Object.class, new MyCellEditor());

        final JFrame frame = new JFrame("JTable DefaultEditor");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(table);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

我使用DefaultTableModel来轻松初始化表。它还返回表中的每个单元格都是可编辑的(显然我们需要至少一个单元格是可编辑的,以便检查程序的有效性)。每个单元格最初都是空的,但如果您启动编辑事件,单元格编辑器不会让您将其留空。

另一种解决方案可能是添加 InputVerifier在编辑器的 JTextField 中,但这在我测试时会有点棘手,所以我宁愿不将其发布在这里,而是选择上面更好的解决方案(Java 教程也建议了) )。

关于java - 在保存到 JTable Cell 之前检查输入有效性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59709975/

相关文章:

java - 如何删除ItemWriter中的对象?

java - 退出 Java 应用程序之前的清理

java - 这就是 Java 中使用自动点击器和 GUI 进行多线程处理的方式吗?

java - 绑定(bind)数据触发更改后 Swing/JTable 不更新

java - jtable 按钮渲染器的按钮编辑器

java - 获取排序的 TableModel

java - java 对象数组

javascript - Java 在缓存中保存 JSP 页面

java - 字符串文字的自动驻留

java - 绘图时 JFrame 边框弄乱坐标