Swing/DateCellEditor の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/DateCellEditor へ行く。
- Swing/DateCellEditor の差分を削除
--- category: swing folder: DateCellEditor title: CellEditorをJSpinnerにして日付を変更 tags: [JTable, TableCellEditor, JSpinner, Focus, ChangeListener] author: aterai pubdate: 2008-09-22T13:48:58+09:00 description: JTableで、日付を表示する列のセルエディタをJSpinnerにします。 image: https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTKdTsjXPI/AAAAAAAAAWA/vtjdEFUkZA4/s800/DateCellEditor.png --- * 概要 [#summary] `JTable`で、日付を表示する列のセルエディタを`JSpinner`にします。 #download(https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTKdTsjXPI/AAAAAAAAAWA/vtjdEFUkZA4/s800/DateCellEditor.png) * サンプルコード [#sourcecode] #code(link){{ class SpinnerCellEditor extends JSpinner implements TableCellEditor { private final JSpinner.DateEditor editor; public SpinnerCellEditor() { super(new SpinnerDateModel()); setEditor(editor = new JSpinner.DateEditor(this, "yyyy/MM/dd")); setArrowButtonEnabled(false); editor.getTextField().setHorizontalAlignment(JFormattedTextField.LEFT); addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { // System.out.println("spinner"); editor.getTextField().requestFocusInWindow(); } }); editor.getTextField().addFocusListener(new FocusAdapter() { @Override public void focusLost(FocusEvent e) { setArrowButtonEnabled(false); } @Override public void focusGained(FocusEvent e) { // System.out.println("getTextField"); setArrowButtonEnabled(true); EventQueue.invokeLater(new Runnable() { @Override public void run() { editor.getTextField().setCaretPosition(8); editor.getTextField().setSelectionStart(8); editor.getTextField().setSelectionEnd(10); } }); } }); setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); } private void setArrowButtonEnabled(boolean flag) { for (Component c : getComponents()) { if (c instanceof JButton) { ((JButton) c).setEnabled(flag); } } } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { setValue(value); return this; } @Override public Object getCellEditorValue() { return getValue(); } // Copied from AbstractCellEditor // protected EventListenerList listenerList = new EventListenerList(); transient protected ChangeEvent changeEvent = null; @Override public boolean stopCellEditing() { try { commitEdit(); } catch (Exception pe) { Toolkit.getDefaultToolkit().beep(); return false; } fireEditingStopped(); return true; } // ... }} * 解説 [#explanation] `TableModel#getColumnClass(int)`で第`2`列目が日付(`Date.class`)を返すように設定し、`JTable#setDefaultEditor(Class,CellEditor)`メソッドで上記のセルエディタを関連付けています。 #code{{ table.setDefaultEditor(Date.class, new SpinnerCellEditor()); table.setSurrendersFocusOnKeystroke(true); }} この日付用のセルエディタ(`SpinnerCellEditor`)は、以下のような動作になっています。 - 日付用のセルエディタ(`SpinnerCellEditor`): -- `SpinnerEditor`で左寄せ --- デフォルトのセルレンダラーと合わせるため --- %%`1.6.0_07`, `1.6.0_06`, `1.5.0_16`などで、`JSpinner`(`WindowsLookAndFeel`)の文字サイズ、余白が微妙に異なる?%% -- ダブルクリックで編集開始 -- 編集開始時のキャレットは先頭の「年(`yyyy`)」ではなく「日(`dd`)」上にあり、この「日(`dd`)」が選択状態になるよう設定 --- 編集開始直後にKBD{Up}、KBD{Down}キーで「日(`dd`)」の値を変更可能にするために必要 -- 編集開始時、スピナエディタにフォーカスが無い場合は、スピナボタンはクリック不可に設定 --- 編集開始と同時に、スピナボタンが押されて日付が変更されるのを防止するため - `SpinnerEditor`で左寄せ -- デフォルトのセルレンダラーと合わせるため -- %%`1.6.0_07`, `1.6.0_06`, `1.5.0_16`などで、`JSpinner`(`WindowsLookAndFeel`)の文字サイズ、余白が微妙に異なる?%% - ダブルクリックで編集開始 - 編集開始時のキャレットは先頭の「年(`yyyy`)」ではなく「日(`dd`)」上にあり、この「日(`dd`)」が選択状態になるよう設定 -- 編集開始直後にKBD{Up}、KBD{Down}キーで「日(`dd`)」の値を変更可能にするために必要 - 編集開始時、スピナエディタにフォーカスが無い場合は、スピナボタンはクリック不可に設定 -- 編集開始と同時に、スピナボタンが押されて日付が変更されるのを防止するため * 参考リンク [#reference] - [[JTableのセルに複数のJButtonを配置する>Swing/MultipleButtonsInTableCell]] * コメント [#comment] #comment - `JTextField`を直接編集して、KBD{Tab}キーなどで編集終了すると`ArrayIndexOutOfBoundsException`が発生するバグを修正。 -- &user(aterai); &new{2013-05-30 (木) 19:56:25}; #comment