Swing/CellEditorFocusCycle の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/CellEditorFocusCycle へ行く。
- Swing/CellEditorFocusCycle の差分を削除
--- category: swing folder: CellEditorFocusCycle title: JTableのセルエディタ内でタブキーによるフォーカス移動を有効にする tags: [JTable, TableCellEditor, Focus, FocusTraversalPolicy] author: aterai pubdate: 2019-03-25T17:24:54+09:00 description: JTableが編集中の場合はセルエディタ内でタブキーによるフォーカス移動が可能になるよう設定します。 image: https://drive.google.com/uc?id=1m3-6T_FyHa51fARDyoZ92MJKfAVox1HjjQ hreflang: href: https://java-swing-tips.blogspot.com/2019/07/enable-focus-move-by-tab-key-in-cell.html lang: en --- * 概要 [#summary] `JTable`が編集中の場合はセルエディタ内でタブキーによるフォーカス移動が可能になるよう設定します。 #download(https://drive.google.com/uc?id=1m3-6T_FyHa51fARDyoZ92MJKfAVox1HjjQ) * サンプルコード [#sourcecode] #code(link){{ JTable table = makeTable(); ActionMap am = table.getActionMap(); Action sncc = am.get("selectNextColumnCell"); Action action = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { if (!table.isEditing() || !isEditorFocusCycle(table.getEditorComponent())) { // System.out.println("Exit editor"); sncc.actionPerformed(e); } } }; am.put("selectNextColumnCell2", action); InputMap im = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), "selectNextColumnCell2"); // ... protected boolean isEditorFocusCycle(Component editor) { Component child = CheckBoxesEditor.getEditorFocusCycleAfter(editor); if (child != null) { child.requestFocus(); return true; } return false; } // ... public static Component getEditorFocusCycleAfter(Component editor) { Component fo = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); if (fo == null || !(editor instanceof Container)) { return null; } Container root = (Container) editor; if (!root.isFocusCycleRoot()) { root = root.getFocusCycleRootAncestor(); } if (root == null) { return null; } // System.out.println("FocusCycleRoot: " + root.getClass().getName()); FocusTraversalPolicy ftp = root.getFocusTraversalPolicy(); Component child = ftp.getComponentAfter(root, fo); if (child != null && SwingUtilities.isDescendingFrom(child, editor)) { // System.out.println("requestFocus: " + child.getClass().getName()); // child.requestFocus(); return child; } return null; } }} * 解説 [#explanation] - 上: デフォルトの`JTable` -- `KeyEvent.VK_TAB`には`selectNextColumnCell`アクションが割り当てられており、このアクションは`table.getCellEditor().stopCellEditing()`メソッドで編集を中断して次のセルを選択する - 下: `selectNextColumnCell`アクションを置換 -- セルエディタが複数の子コンポーネントを持つ`FocusCycleRoot`コンポーネントであり、そのセルが編集中の場合は`FocusTraversalPolicy`を取得してセル内でフォーカス移動、編集中でない場合は`selectNextColumnCell`アクションを実行するアクションを作成して、`KeyEvent.VK_TAB`に割り当てる -- このサンプルではKBD{Shift+Tab}での逆順フォーカス移動には対応していないので、編集が中断されて前のセルにフォーカスが移動する -- このサンプルではKBD{Shift+Tab}での逆順フォーカス移動には対応していないので、セル編集が中断されて前のセルにフォーカスが移動する * 参考リンク [#reference] - [[JTableの列にEnumSetを使用する>Swing/EnumSet]] * コメント [#comment] #comment #comment