在保存到 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);
}

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

但是,将出现一个错误,指出Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError

a.(有人可以解释错误以及如何解决问题吗?

b.(或者有没有更好的方法来实现在退出编辑模式或保存表之前检查用户输入的侦听器?

编辑:我尝试实现CellEditorListener,如以下示例所示:

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

这反过来又提示了错误Exception in thread "main" java.lang.NullPointerException。关于CellEditorListener的文档并不多,也不太了解它是如何工作的以及如何使用它。

根据相应 Java 教程的相应部分,如果编辑器不应该失去焦点或true,您可以覆盖DefaultCellEditorstopCellEditing以返回false。这意味着我们可以使用它首先检查用户输入,然后根据用户的输入,如果他/她输入无效文本(或true如果他/她输入有效文本(,则返回false

在下面的示例代码中,我使用了一个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轻松初始化表。它还返回表中的每个单元格都是可编辑的(我们显然需要至少一个单元格是可编辑的,以便检查程序的有效性(。每个单元格最初都是空的,但如果您启动编辑事件,单元格编辑器不会允许您将其留空。

另一种解决方案可能是在编辑器的JTextField中添加一个InputVerifier,但是当我测试它时,这会更加棘手,所以我宁愿不在这里发布它,以支持更好的上述解决方案(也是Java教程建议的(。

最新更新