Swing/ScrollingCellEditor の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/ScrollingCellEditor へ行く。
- Swing/ScrollingCellEditor の差分を削除
--- category: swing folder: ScrollingCellEditor title: TableCellEditorをスクロール可能にする tags: [JTable, JScrollPane, JTextArea, TableCellEditor, Focus] author: aterai pubdate: 2011-06-20T14:39:55+09:00 description: JTableのTableCellEditorとして、JTextAreaとJScrollPaneを使用します。 image: https://lh4.googleusercontent.com/-DDRbJ9WhSJk/Tf7btYjUE7I/AAAAAAAAA9s/yVKIKC55zIw/s800/ScrollingCellEditor.png --- * 概要 [#summary] `JTable`の`TableCellEditor`として、`JTextArea`と`JScrollPane`を使用します。 #download(https://lh4.googleusercontent.com/-DDRbJ9WhSJk/Tf7btYjUE7I/AAAAAAAAA9s/yVKIKC55zIw/s800/ScrollingCellEditor.png) * サンプルコード [#sourcecode] #code(link){{ class TextAreaCellEditor extends JTextArea implements TableCellEditor { class TextAreaCellEditor extends AbstractCellEditor implements TableCellEditor { private static final String KEY = "Stop-Cell-Editing"; protected transient ChangeEvent changeEvent; private final JScrollPane scroll; private final JTextArea textArea = new JTextArea(); private final JScrollPane scroll = new JScrollPane(textArea); protected TextAreaCellEditor() { super(); scroll = new JScrollPane(this); scroll.setBorder(BorderFactory.createEmptyBorder()); // scroll.setViewportBorder(BorderFactory.createEmptyBorder()); setLineWrap(true); setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4)); textArea.setLineWrap(true); textArea.setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4)); KeyStroke enter = KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, InputEvent.CTRL_DOWN_MASK); getInputMap(JComponent.WHEN_FOCUSED).put(enter, KEY); getActionMap().put(KEY, new AbstractAction() { int modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); // Java 10: int modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx(); KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, modifiers); textArea.getInputMap(JComponent.WHEN_FOCUSED).put(enter, KEY); textArea.getActionMap().put(KEY, new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { stopCellEditing(); } }); } @Override public Object getCellEditorValue() { return getText(); return textArea.getText(); } @Override public Component getTableCellEditorComponent( JTable table, Object value, boolean isSelected, int row, int column) { System.out.println("getTableCellEditorComponent"); setFont(table.getFont()); setText(Objects.toString(value, "")); EventQueue.invokeLater(new Runnable() { @Override public void run() { setCaretPosition(getText().length()); requestFocusInWindow(); System.out.println("invokeLater: getTableCellEditorComponent"); } JTable table, Object value, boolean isSelected, int row, int column) { // System.out.println("getTableCellEditorComponent"); textArea.setFont(table.getFont()); textArea.setText(Objects.toString(value, "")); EventQueue.invokeLater(() -> { textArea.setCaretPosition(textArea.getText().length()); textArea.requestFocusInWindow(); System.out.println("invokeLater: getTableCellEditorComponent"); }); return scroll; } @Override public boolean isCellEditable(final EventObject e) { @Override public boolean isCellEditable(EventObject e) { if (e instanceof MouseEvent) { return ((MouseEvent) e).getClickCount() >= 2; } System.out.println("isCellEditable"); EventQueue.invokeLater(new Runnable() { @Override public void run() { if (e instanceof KeyEvent) { KeyEvent ke = (KeyEvent) e; char kc = ke.getKeyChar(); if (Character.isUnicodeIdentifierStart(kc)) { setText(getText() + kc); System.out.println("invokeLater: isCellEditable"); } // System.out.println("isCellEditable"); EventQueue.invokeLater(() -> { if (e instanceof KeyEvent) { KeyEvent ke = (KeyEvent) e; char kc = ke.getKeyChar(); if (Character.isUnicodeIdentifierStart(kc)) { textArea.setText(textArea.getText() + kc); System.out.println("invokeLater: isCellEditable"); } } }); return true; } // ... } }} * 解説 [#explanation] 上記のサンプルでは、`0`列目にデフォルトの`TableCellEditor(JTextField)`、`1`列目に`JTextArea`を継承した`TableCellEditor`を設定しています。 - `TableCellEditor#isCellEditable(...)` -- マウスのダブルクリックで編集開始 - `TableCellEditor#getTableCellEditorComponent(...)` -- `JTextArea`に現在表示されているセル文字列をコピーし、戻り値の`Component`として`JScrollPane`を返す - `TableCellEditor#isCellEditable(...)`、`EventQueue.invokeLater(...)` -- キー入力で編集開始した場合、その入力を`JTextArea`の文字列末尾に追加 -- [https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Character.html#isUnicodeIdentifierStart-char- Character#isUnicodeIdentifierStart(char) (Java Platform SE 8)] - `TableCellEditor#getTableCellEditorComponent(...)`、`EventQueue.invokeLater(...)` -- `JTextArea`にフォーカスを移動し`JTextArea`のキャレットも文字列末尾に移動 * 参考リンク [#reference] - [[TableCellEditorのレイアウトを変更>Swing/CellEditorLayout]] - [[JTableのセル幅で文字列を折り返し>Swing/TableCellRenderer]] * コメント [#comment] #comment #comment