概要

JTableHeaderのカラムを選択不可にして、ソートなどを禁止します。

スクリーンショット

DisabledHeader.png

サンプルコード

public class SortButtonRenderer extends JButton implements TableCellRenderer {
  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    JButton button = this;
    if (!isEnabledAt(column)) {
      button.setText((value == null) ? "" : value.toString());
      button.getModel().setEnabled(false);
      return button;
    }
    // ...
  }
}

private final HashMap dmap = new HashMap();
public boolean isEnabledAt(int col) {
  Integer oi = Integer.valueOf(col);
  if (dmap.containsKey(oi)) {
    Boolean b = (Boolean) dmap.get(oi);
    return b.booleanValue();
  } else {
    return true;
  }
}
View in GitHub: Java, Kotlin

解説

サンプルでは、0列目のカラムヘッダを常に選択不可に、3列目はチェックボックスで選択できるかどうかを切り替えるようにしています。

  • HashMapに選択不可にするカラムヘッダを設定してレンダラーがヘッダを描画するときにそれをsetEnabled(false)に変更
  • TableSorter.javaを使用してソートしている場合は、TableSorterのインナークラスのMouseHandlerを例えば以下のように変更すると任意のカラムがクリックしてもソート不可になる
    private class MouseHandler extends MouseAdapter {
      @Override public void mouseClicked(MouseEvent e) {
        JTableHeader h = (JTableHeader) e.getSource();
        TableColumnModel columnModel = h.getColumnModel();
        int viewColumn = columnModel.getColumnIndexAtX(e.getX());
        int column = columnModel.getColumn(viewColumn).getModelIndex();
        // ここを変更
        if (isSortableIndex(column)) { // column != -1 ) {
          int status = getSortingStatus(column);
          if (!e.isControlDown()) {
            cancelSorting();
          }
          status = status + (e.isShiftDown() ? -1 : 1);
          status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 1}
          setSortingStatus(column, status);
        }
      }
    }
    

  • JDK 1.6.0で導入されたTableRowSorterを使用する場合、DefaultRowSorter#setSortable(int, boolean)でソート不可にするカラムを指定可能
    • ソート不可の列の表示は以下のようなレンダラーで切り替え可能(参考: TableRowSorterでJTableのソート)
      final JTableHeader hd = table.getTableHeader();
      final TableCellRenderer headerRenderer = hd.getDefaultRenderer();
      hd.setDefaultRenderer(new TableCellRenderer() {
        @Override public Component getTableCellRendererComponent(JTable tbl, Object val,
            boolean isS, boolean hasF, int row, int col) {
          JLabel lbl = (JLabel) headerRenderer.getTableCellRendererComponent(
            tbl, val, isS, hasF, row, col);
          int modelColumnIndex = tbl.convertColumnIndexToModel(col);
          lbl.setForeground(sorter.isSortable(modelColumnIndex) ? Color.BLACK : Color.GRAY);
          return lbl;
        }
      });
      

参考リンク

コメント