• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:TableCellEditorをスクロール可能にする
#navi(../)
#tags(JTable, JScrollPane, JTextArea, TableCellEditor, Focus)
RIGHT:Posted by &author(aterai); at 2011-06-20
*TableCellEditorをスクロール可能にする [#i988a941]
JTableのTableCellEditorとして、JTextAreaとJScrollPaneを使用します。
``JTable``の``TableCellEditor``として、``JTextArea``と``JScrollPane``を使用します。

-&jnlp;
-&jar;
-&zip;

//#screenshot
#ref(https://lh4.googleusercontent.com/-DDRbJ9WhSJk/Tf7btYjUE7I/AAAAAAAAA9s/yVKIKC55zIw/s800/ScrollingCellEditor.png)

**サンプルコード [#gf065aec]
#code(link){{
class TextAreaCellEditor extends JTextArea implements TableCellEditor {
  private final JScrollPane scroll;
  public TextAreaCellEditor() {
    scroll = new JScrollPane(this);
    setLineWrap(true);
    KeyStroke enter = KeyStroke.getKeyStroke(
        KeyEvent.VK_ENTER, InputEvent.CTRL_MASK);
    getInputMap(JComponent.WHEN_FOCUSED).put(enter, new AbstractAction() {
      @Override public void actionPerformed(ActionEvent e) {
        stopCellEditing();
      }
    });
  }
  @Override public Object getCellEditorValue() {
    return getText();
  }
  @Override public Component getTableCellEditorComponent(
      JTable table, Object value, boolean isSelected, int row, int column) {
    setFont(table.getFont());
    setText((value!=null)?value.toString():"");
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        setCaretPosition(getText().length());
        requestFocusInWindow();
      }
    });
    return scroll;
  }
  @Override public boolean isCellEditable(final EventObject e) {
    if(e instanceof MouseEvent) {
      return ((MouseEvent)e).getClickCount() >= 2;
    }
    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);
          }
        }
      }
    });
    return true;
  }
//......
}}

**解説 [#nc5d399e]
上記のサンプルでは、0列目にデフォルトの TableCellEditor(JTextField)、1列目に JTextArea を継承した TableCellEditor を設定しています。
上記のサンプルでは、0列目にデフォルトの``TableCellEditor(JTextField)``、1列目に``JTextArea``を継承した``TableCellEditor``を設定しています。

+ TableCellEditor#isCellEditable
+ ``TableCellEditor#isCellEditable``
-- マウスのダブルクリックで編集開始
+ TableCellEditor#getTableCellEditorComponent
-- JTextAreaに現在表示されているセル文字列をコピーし、戻り値のComponentとして、JScrollPaneを返す
+ TableCellEditor#isCellEditable, EventQueue.invokeLater
-- キー入力で編集開始した場合、その入力をJTextAreaの文字列末尾に追加
+ TableCellEditor#getTableCellEditorComponent, EventQueue.invokeLater
-- JTextAreaにフォースを移動し、JTextAreaのキャレットも文字列末尾に移動
+ ``TableCellEditor#getTableCellEditorComponent``
-- ``JTextArea``に現在表示されているセル文字列をコピーし、戻り値の``Component``として、``JScrollPane``を返す
+ ``TableCellEditor#isCellEditable``, ``EventQueue.invokeLater``
-- キー入力で編集開始した場合、その入力を``JTextArea``の文字列末尾に追加
+ ``TableCellEditor#getTableCellEditorComponent``, ``EventQueue.invokeLater``
-- ``JTextArea``にフォースを移動し、``JTextArea``のキャレットも文字列末尾に移動

**参考リンク [#wcd8d89d]
- [[TableCellEditorのレイアウトを変更>Swing/CellEditorLayout]]
- [[JTableのセル幅で文字列を折り返し>Swing/TableCellRenderer]]

**コメント [#w195090b]
#comment