Java 如何防止JTable在指定列中接受特定输入?
我试图得到一个JTable,它只接受每列特定格式的输入。例如,在一个有5列的表中,索引3和4处的表应该只接受数值 我知道RowFilter和RowFilter.regexFilter。。。因为,但这会隐藏整行,而不仅仅是放弃更改,甚至会阻止在添加行后立即显示空行。以下是我尝试将其用作示例的方式:Java 如何防止JTable在指定列中接受特定输入?,java,swing,jtable,Java,Swing,Jtable,我试图得到一个JTable,它只接受每列特定格式的输入。例如,在一个有5列的表中,索引3和4处的表应该只接受数值 我知道RowFilter和RowFilter.regexFilter。。。因为,但这会隐藏整行,而不仅仅是放弃更改,甚至会阻止在添加行后立即显示空行。以下是我尝试将其用作示例的方式: public static void main(String[] args) { // Create empty table with 5 columns JTable table =
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的editingStoppedChangeEvent 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关于覆盖GetColumnClasint列的建议听起来似乎可以很好地工作。我没有尝试,因为我需要更多的复杂性。我想说的是,提供一个合适的单元格编辑器。例如,在一个有5列的表中,索引3和4处的那些应该只接受数值。-这与划船分拣机无关。您需要重写getColumnClass方法以返回这些列的Integer.class。该表将选择一个只允许数值的整数编辑器。我修改了我的代码以更好地适应mre的描述。尽管看起来很奇怪,但进一步减少代码片段的方法更不像是MRE/SSCCE。问题是&这是一个常见的误解,它不完全是关于最小/短的。我成功地做到了这一点,祝贺你解决了这个问题&+1感谢你的反馈。话虽如此,请再次访问,尤其是上的页面,该页面将更详细地回顾构成MRE/SSCCE标签的其他元素。发布一个会帮助别人帮助你。@AndrewThompson更不像mre。你说得对。因为这篇文章的第一个版本几乎是你能为这个问题提供的最好的mre,我希望这次你能让我解释一下原因。让我们看一下SCSCE的每一个点,好吗?短:25行带注释和间隙:远低于100行。TfT、PrS和SC:本例中的每一行都有它的用途,并有助于使其成为最可运行的。更正:有些行可能太长了,但这不会影响可读性,而且格式也很好。请原谅我听起来有些自大,但我在这里受到了注释长度的限制。本质上我要说的是,这个例子满足了你发布的链接中几乎所有的要求,因此应该被认为是一个有效的mre。如果你认为没有,请解释原因。哦,为了记录在案,我回到了这篇文章的原始版本。