我想在每次更改 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 ,您可以覆盖 stopCellEditing
的DefaultCellEditor
如果编辑器不应失去焦点,则返回 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/