如何将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()
方法。