概要

JTableのセルエディタへの入力が妥当かをInputVerifierなどを使用して検証します。

サンプルコード

TableModel model = new DefaultTableModel(columnNames, 10) {
  @Override public Class<?> getColumnClass(int column) {
    return Integer.class;
  }
};
JTable table = new JTable(model) {
  @Override public Component prepareEditor(TableCellEditor editor, int row, int column) { 
    Component c = super.prepareEditor(editor, row, column);
    ((JComponent) c).setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
    return c;
  }
};

JTextField textField2 = new JTextField();
textField2.setInputVerifier(new IntegerInputVerifier());
table.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(textField2) {
  @Override public boolean stopCellEditing() {
    JComponent editor = (JComponent) getComponent();
    boolean isEditValid = editor.getInputVerifier().verify(editor);
    editor.setBorder(isEditValid ? BorderFactory.createEmptyBorder(1, 1, 1, 1)
                                 : BorderFactory.createLineBorder(Color.RED));
    return isEditValid && super.stopCellEditing();
  }
});
View in GitHub: Java, Kotlin

解説

  • Default
    • デフォルトのJTable.NumberEditor(JTable.GenericEditorを継承)を使用
    • 数値以外を入力し、EnterTabキーで編集確定を実行するとエディタの縁が赤くなりフォーカス移動がキャンセルされる
  • DocumentFilter
    • セルエディタに数値以外の入力を禁止するDocumentFilterAbstractDocument#setDocumentFilter(...)でメソッドで設定し、TableColumn#setCellEditor(...)で1列目のセルエディタとして設定
  • InputVerifier
    • セルエディタにInputVerifierを設定し、TableColumn#setCellEditor(...)で2列目のセルエディタとして設定
    • EnterTabキーで編集確定するCellEditor#stopCellEditing()メソッドを実行したとき自然数、または空文字以外が入力されている場合はエディタの縁を赤に変更してフォーカス移動をキャンセルする
  • JFormattedTextField
    • セルエディタにJFormattedTextFieldを設定し、TableColumn#setCellEditor(...)で3列目のセルエディタとして設定
    • Tabキーで編集確定するCellEditor#stopCellEditing()メソッドを実行したとき、数値以外が入力されている場合はエディタの縁を赤に変更してフォーカス移動をキャンセルする
      • デフォルトのJFormattedTextFieldの場合、Enterキーの入力でJFormattedTextField側のInputMapで定義されたアクションでフォーカス移動がキャンセルされ、CellEditor#stopCellEditing()は実行されないのでエディタの縁は変化しない

  • ESCでセルエディタの編集をキャンセルしたときエディタの縁が赤のまま残ってしまう場合があるので、JTable#prepareEditor(...)メソッドをオーバーライドして縁を初期化
    JTable table = new JTable(model) {
      @Override public Component prepareEditor(TableCellEditor editor, int row, int column) { 
        Component c = super.prepareEditor(editor, row, column);
        ((JComponent) c).setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
        return c;
      }
    };
    

参考リンク

コメント