---
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 [#summary]
`JTable`の`TableCellEditor`として、`JTextArea`と`JScrollPane`を使用します。
#download(https://lh4.googleusercontent.com/-DDRbJ9WhSJk/Tf7btYjUE7I/AAAAAAAAA9s/yVKIKC55zIw/s800/ScrollingCellEditor.png)
* Source Code Examples [#sourcecode]
#code(link){{
class TextAreaCellEditor extends AbstractCellEditor implements TableCellEditor {
private static final String KEY = "Stop-Cell-Editing";
private final JTextArea textArea = new JTextArea();
private final JScrollPane scroll = new JScrollPane(textArea);
protected TextAreaCellEditor() {
super();
scroll.setBorder(BorderFactory.createEmptyBorder());
// scroll.setViewportBorder(BorderFactory.createEmptyBorder());
textArea.setLineWrap(true);
textArea.setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4));
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 textArea.getText();
}
@Override public Component 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(EventObject e) {
if (e instanceof MouseEvent) {
return ((MouseEvent) e).getClickCount() >= 2;
}
// 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;
}
}
}}
* Description [#explanation]
* Description [#description]
上記のサンプルでは、`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 [#reference]
- [[TableCellEditorのレイアウトを変更>Swing/CellEditorLayout]]
- [[JTableのセル幅で文字列を折り返し>Swing/TableCellRenderer]]
* Comment [#comment]
#comment
#comment