Как пометить вход ячейки JTable как недействительный?

Если я возьму JTable и задаю class кластера на его модели следующим образом:

  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 выполняет отклонение по умолчанию, но я не могу найти его.

Как я могу заставить его отклонять неположительный вход так же, как он отклоняет вход не Integer?

благодаря

private static class JTable.GenericEditor использует интроспекцию для исключения исключений, возникающих при построении определенных подclassов Number с недопустимыми значениями String . Если вам не требуется такое общее поведение, подумайте о создании PositiveIntegerCellEditor в качестве подclassа DefaultCellEditor . Ваш stopCellEditing() будет соответственно проще.

Приложение: Обновлено для использования выравнивания RIGHT и общего кода ошибки.

Добавление: см. Также Использование редактора для проверки введенного пользователем текста .

введите описание изображения здесь

  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 scope, я не могу переопределить GenericEditor чтобы предоставить эту функцию, и вам придется повторно реализовать ее с несколькими настройками, если у кого-то нет лучшего способа сделать это, что я «Мне нравится слышать.

  @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() .

  • Проверка файла XML на локальный DTD-файл с помощью Java
  • Как проверить массив входов с помощью validate plugin jquery
  • Как проверить файл XML с помощью Java с XSD с включенным?
  • как я могу проверить ввод пользователя как двойной в C ++?
  • Проверка даты в C #
  • Как заполнить текстовое поле с помощью PrimeFaces AJAX после ошибок проверки?
  • Проверка адресов IPv4 с регулярным выражением
  • C # WinForms ErrorProvider Control
  • Шаблон Regex для совпадения как минимум 1 числа и 1 символа в строке
  • Обнаружение события JTextField «отменить выбор»
  • Результат Struts2 INPUT: как он работает? Как обрабатываются ошибки преобразования / проверки?
  • Давайте будем гением компьютера.