如何防止 JTable 在指定列中获取特定输入?
How do I prevent a JTable from taking a certain input in the specified column?
我正在尝试让 JTable
只接受每列特定格式的输入。例如,在具有 5 列的 table 中,索引 3 和 4 处的列应该只接受数值。
我知道 RowFilter
和 RowFilter.regexFilter(...)
因为 ,但这隐藏了整行而不是仅仅丢弃更改,甚至阻止空行在之后立即显示添加它们。这就是我尝试使用它的方式(又名示例):
public static void main(String[] args) {
// Create empty table with 5 columns
JTable table = new JTable(new DefaultTableModel(new String[][] {}, new String[] { "String", "String", "String", "Num", "Num" }));
// Create a new table row sorter
TableRowSorter<TableModel> sorter = new TableRowSorter<>(table.getModel());
// Filter columns 4 and 5 to only contain numbers
sorter.setRowFilter(RowFilter.regexFilter("[0-9]+", 3, 4));
// Apply the sorter to the table
table.setRowSorter(sorter);
// Boilerplate JFrame setup in case you want to run this
JFrame frame = new JFrame("MRE");
JPanel contentPane = new JPanel();
JButton addRow = new JButton("Add Row");
addRow.addActionListener((event) -> ((DefaultTableModel) table.getModel()).addRow(new String[] {}));
contentPane.add(new JScrollPane(table));
contentPane.add(addRow);
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(contentPane);
frame.setVisible(true);
}
TL;DR:如果输入的值不被允许或者在输入阶段甚至不接受错误的输入,我希望单元格恢复它们之前的值。
我通过覆盖 JTable 的 editingStopped(ChangeEvent e)
方法设法做到了。您可能应该使用 TableCellEditor
来做到这一点,但我发现这样做更容易:
public class MyTable extends JTable {
// Contains the check for each column
private final Map<Integer, Function<String, Boolean>> checks = new HashMap<>();
public STable(TableModel model) {
super(model);
// Fill the map
checks.put(0, (str) -> ...);
checks.put(3, (str) -> ...);
checks.put(4, (str) -> ...);
}
@Override
public void editingStopped(ChangeEvent e) {
String value = getCellEditor().getCellEditorValue().toString();
final Function<String, Boolean> checker = checks.get(getSelectedColumn());
if (checker != null && !checker.apply(value))
getCellEditor().cancelCellEditing();
else
super.editingStopped(e);
}
}
此外,我没有尝试过,但 camickr 的覆盖 getColumnClass(int column)
的建议听起来效果不错。我没有尝试,因为我需要比这更复杂的东西。
我正在尝试让 JTable
只接受每列特定格式的输入。例如,在具有 5 列的 table 中,索引 3 和 4 处的列应该只接受数值。
我知道 RowFilter
和 RowFilter.regexFilter(...)
因为
public static void main(String[] args) {
// Create empty table with 5 columns
JTable table = new JTable(new DefaultTableModel(new String[][] {}, new String[] { "String", "String", "String", "Num", "Num" }));
// Create a new table row sorter
TableRowSorter<TableModel> sorter = new TableRowSorter<>(table.getModel());
// Filter columns 4 and 5 to only contain numbers
sorter.setRowFilter(RowFilter.regexFilter("[0-9]+", 3, 4));
// Apply the sorter to the table
table.setRowSorter(sorter);
// Boilerplate JFrame setup in case you want to run this
JFrame frame = new JFrame("MRE");
JPanel contentPane = new JPanel();
JButton addRow = new JButton("Add Row");
addRow.addActionListener((event) -> ((DefaultTableModel) table.getModel()).addRow(new String[] {}));
contentPane.add(new JScrollPane(table));
contentPane.add(addRow);
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(contentPane);
frame.setVisible(true);
}
TL;DR:如果输入的值不被允许或者在输入阶段甚至不接受错误的输入,我希望单元格恢复它们之前的值。
我通过覆盖 JTable 的 editingStopped(ChangeEvent e)
方法设法做到了。您可能应该使用 TableCellEditor
来做到这一点,但我发现这样做更容易:
public class MyTable extends JTable {
// Contains the check for each column
private final Map<Integer, Function<String, Boolean>> checks = new HashMap<>();
public STable(TableModel model) {
super(model);
// Fill the map
checks.put(0, (str) -> ...);
checks.put(3, (str) -> ...);
checks.put(4, (str) -> ...);
}
@Override
public void editingStopped(ChangeEvent e) {
String value = getCellEditor().getCellEditorValue().toString();
final Function<String, Boolean> checker = checks.get(getSelectedColumn());
if (checker != null && !checker.apply(value))
getCellEditor().cancelCellEditing();
else
super.editingStopped(e);
}
}
此外,我没有尝试过,但 camickr 的覆盖 getColumnClass(int column)
的建议听起来效果不错。我没有尝试,因为我需要比这更复杂的东西。