概要

JTableの行と列のSelectionModelListSelectionListenerを追加し、選択されたセルの情報を書き出すテストを行っています。

サンプルコード

JTable table1 = new JTable(model);
table1.setCellSelectionEnabled(true);
ListSelectionListener selectionListener1 = new AbstractTableCellSelectionListener() {
  @Override public void valueChanged(ListSelectionEvent e) {
    if (e.getValueIsAdjusting()) {
      return;
    }
    int sr = table1.getSelectionModel().getLeadSelectionIndex();
    int sc = table1.getColumnModel().getSelectionModel().getLeadSelectionIndex();
    if (getRowColumnAdjusting(sr, sc)) {
      return;
    }
    Object o = table1.getValueAt(sr, sc);
    textArea.append(String.format("(%d, %d) %s%n", sr, sc, o));
    textArea.setCaretPosition(textArea.getDocument().getLength());
  }
};
table1.getSelectionModel().addListSelectionListener(selectionListener1);
table1.getColumnModel().getSelectionModel().addListSelectionListener(selectionListener1);
// ...
abstract class AbstractTableCellSelectionListener implements ListSelectionListener {
  private int prevRow = -1;
  private int prevCol = -1;
  protected boolean getRowColumnAdjusting(int sr, int sc) {
    boolean flg = prevRow == sr && prevCol == sc;
    prevRow = sr;
    prevCol = sc;
    return flg;
  }
}
View in GitHub: Java, Kotlin

解説

  • JTable
    • JTable#getSelectionModel()JTable#getColumnModel()#getSelectionModel()で取得した行と列のSelectionModelに共通のListSelectionListenerを追加し、選択されたセルの内容と行列番号を表示
    • JTable#getSelectedRow()JTable#getSelectedColumn()を使用しているため、Shift+クリックなどで範囲選択した場合アンカーインデックスが現在選択しているセルになる
      • 同一セルが選択された場合は選択セルの内容を書き出さないよう設定しているため、これらの範囲選択ではなにも書き出されない
    • Ctrl+Aで全選択すると常に(0, 0)のセル情報が書き出される(直前に選択されているのが(0, 0)の場合は除く)
  • SelectionModel
    • JTable#getSelectionModel()JTable#getColumnModel()#getSelectionModel()で取得した行と列のSelectionModelに共通のListSelectionListenerを追加し、選択されたセルの内容と行列番号を表示
    • JTable#getSelectionModel()#getLeadSelectionIndex()JTable#getColumnModel()#getSelectionModel()#getLeadSelectionIndex()を使用しているため、Shift+クリックなどで範囲選択した場合リードインデックスが現在選択しているセルになる
      • 範囲選択するとマウスをリリースした位置のセル情報が書き出される
    • Ctrl+Aで全選択してもリードインデックスは変化しないため、セル情報は書き出されない
  • Row/Column
    • JTable#getSelectionModel()JTable#getColumnModel()#getSelectionModel()で取得した行と列のSelectionModelに別々のListSelectionListenerを追加し、選択インデックスを表示
    • 行と列で異なるListSelectionListenerを追加しているため、1回のマウス選択などで2回情報が書き出される場合がある
    • 範囲選択した場合、常にListSelectionEvent#getFirstIndex() <= ListSelectionEvent#getLastIndex()
      • 例えば(2, 2)のセルから(0, 0)へ範囲選択した場合、ListSelectionEvent#getFirstIndex()0ListSelectionEvent#getLastIndex()2
      • アンカーインデックス、リードインデックスを取得する場合はListSelectionModel#getAnchorSelectionIndex()ListSelectionModel#getLeadSelectionIndex()を使用する
  • changeSelection
    • JTable#changeSelection(...)メソッドをオーバーライドして選択セル情報を書き出す
    • 範囲選択中(ListSelectionEvent#getValueIsAdjusting())を除外していないため、マウスでドラッグされたセル情報などもすべて書き出される

参考リンク

コメント