• title: JTableHeaderのハイライト表示 tags: [JTable, JTableHeader, TableCellRenderer, ListSelectionModel] author: aterai pubdate: 2014-12-29T00:02:59+09:00 description: JTableのセルが選択されている場合、そのセルが存在するカラムヘッダにフォーカスを設定します。

概要

JTableのセルが選択されている場合、そのセルが存在するカラムヘッダにフォーカスを設定します。

サンプルコード

class ColumnHeaderRenderer implements TableCellRenderer {
  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    TableCellRenderer r = table.getTableHeader().getDefaultRenderer();
    ListSelectionModel csm = table.getColumnModel().getSelectionModel();
    boolean f = csm.getLeadSelectionIndex() == column ? true : hasFocus;
    return r.getTableCellRendererComponent(table, value, isSelected, f, row, column);
  }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、リードインデックスがある場合はフォーカスありで自身を描画するヘッダセルレンダラーを作成し、これをTableColumn#setHeaderRenderer(...)ですべてのカラムに設定しています。

  • JTable内にあるセルの選択状態が変更されても、JTableHeaderの描画には影響しない
    • このため、TableColumnModelから取得したSelectionModelListSelectionListenerを追加して、リードインデックスの移動イベントが発生するたび、JTableHeader#repaint()を呼び出してJTableHeaderのフォーカス変更を描画し直すように設定
TableColumnModel cm = table.getColumnModel();
cm.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
  @Override public void valueChanged(ListSelectionEvent e) {
    header.repaint();
  }
});

コメント