如何将JTable单元格输入标记为无效?

如果我使用JTable并在其模型上指定列的classtype,如下所示:

  DefaultTableModel model = new DefaultTableModel(columnNames, 100) { @Override public Class getColumnClass(int columnIndex) { return Integer.class; }}; 

然后,每当用户尝试在表格中输入double值时,Swing会自动拒绝输入并将单元格的轮廓设置为红色。

当某人输入单元格的“负数或0”输入时,我希望发生相同的效果。 我有这个:

  @Override public void setValueAt(Object val, int rowIndex, int columnIndex) { if (val instanceof Number && ((Number) val).doubleValue() > 0) { super.setValueAt(val, rowIndex, columnIndex); } } } 

这可以防止单元格接受任何非正值,但不会将颜色设置为红色并使单元格保持可编辑状态。

我试着调查JTable默认情况下是如何做出拒绝的,但我似乎无法找到它。

如何拒绝非正输入与拒绝非整数输入相同?

谢谢

private static class JTable.GenericEditor使用内省来捕获通过使用无效的String值构造特定的Number子类而引发的exception。 如果您不需要此类通用行为,请考虑将PositiveIntegerCellEditor创建为DefaultCellEditor的子类。 你的stopCellEditing()方法会相应简单。

附录:已更新以使用RIGHT对齐和常见错误代码。

附录:另请参阅使用编辑器validation用户输入的文本

在此处输入图像描述

  private static class PositiveIntegerCellEditor extends DefaultCellEditor { private static final Border red = new LineBorder(Color.red); private static final Border black = new LineBorder(Color.black); private JTextField textField; public PositiveIntegerCellEditor(JTextField textField) { super(textField); this.textField = textField; this.textField.setHorizontalAlignment(JTextField.RIGHT); } @Override public boolean stopCellEditing() { try { int v = Integer.valueOf(textField.getText()); if (v < 0) { throw new NumberFormatException(); } } catch (NumberFormatException e) { textField.setBorder(red); return false; } return super.stopCellEditing(); } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { textField.setBorder(black); return super.getTableCellEditorComponent( table, value, isSelected, row, column); } } 

我想到了。 如果给定的数字不是正数,则覆盖DefaultCellEditor并返回false /将边框设置为红色。

不幸的是,由于JTable.GenericEditor是static w / default范围,我无法覆盖GenericEditor以提供此function,并且必须通过一些调整重新实现它,除非有人有更好的方法这样做,我我想听。

  @SuppressWarnings("serial") class PositiveNumericCellEditor extends DefaultCellEditor { Class[] argTypes = new Class[]{String.class}; java.lang.reflect.Constructor constructor; Object value; public PositiveNumericCellEditor() { super(new JTextField()); getComponent().setName("Table.editor"); ((JTextField)getComponent()).setHorizontalAlignment(JTextField.RIGHT); } public boolean stopCellEditing() { String s = (String)super.getCellEditorValue(); if ("".equals(s)) { if (constructor.getDeclaringClass() == String.class) { value = s; } super.stopCellEditing(); } try { value = constructor.newInstance(new Object[]{s}); if (value instanceof Number && ((Number) value).doubleValue() > 0) { return super.stopCellEditing(); } else { throw new RuntimeException("Input must be a positive number."); } } catch (Exception e) { ((JComponent)getComponent()).setBorder(new LineBorder(Color.red)); return false; } } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { this.value = null; ((JComponent)getComponent()).setBorder(new LineBorder(Color.black)); try { Class type = table.getColumnClass(column); if (type == Object.class) { type = String.class; } constructor = type.getConstructor(argTypes); } catch (Exception e) { return null; } return super.getTableCellEditorComponent(table, value, isSelected, row, column); } public Object getCellEditorValue() { return value; } } 

此代码是对已接受答案的一个小改进。 如果用户未输入任何值,则单击另一个单元格应允许他选择另一个单元格。 已接受的解决方案不允许这样做。

 @Override public boolean stopCellEditing() { String text = field.getText(); if ("".equals(text)) { return super.stopCellEditing(); } try { int v = Integer.valueOf(text); if (v < 0) { throw new NumberFormatException(); } } catch (NumberFormatException e) { field.setBorder(redBorder); return false; } return super.stopCellEditing(); } 

此解决方案检查空文本。 如果是空文本,我们调用stopCellEditing()方法。