• category: swing folder: DisableRightButtonReordering title: JTableHeaderの列をマウスの右ボタンドラッグで順序変更不可にする tags: [JTable, JTableHeader, TableColumn, JLayer] author: aterai pubdate: 2019-12-23T14:45:20+09:00 description: JLayerを使用してJTableHeaderの列をマウスの右ボタンでドラッグしても順序変更不可に設定します。 image: https://drive.google.com/uc?id=1fETWKkk9g8-SRVPtWT7UmZhoBEue-8rK

概要

JLayerを使用してJTableHeaderの列をマウスの右ボタンでドラッグしても順序変更不可に設定します。

サンプルコード

class DisableRightButtonSwapLayerUI extends LayerUI<JScrollPane> {
  @Override public void installUI(JComponent c) {
    super.installUI(c);
    if (c instanceof JLayer) {
      ((JLayer<?>) c).setLayerEventMask(AWTEvent.MOUSE_MOTION_EVENT_MASK);
    }
  }

  @Override public void uninstallUI(JComponent c) {
    if (c instanceof JLayer) {
      ((JLayer<?>) c).setLayerEventMask(0);
    }
    super.uninstallUI(c);
  }

  @Override protected void processMouseMotionEvent(MouseEvent e, JLayer<? extends JScrollPane> l) {
    int id = e.getID();
    Component c = e.getComponent();
    if (c instanceof JTableHeader &&
         id == MouseEvent.MOUSE_DRAGGED &&
         SwingUtilities.isRightMouseButton(e)) {
      e.consume();
    }
  }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、JTableHeaderの列をマウスの右ボタンでドラッグした場合のみ順序変更不可に設定しています。

  • Default
    • 右ボタンでドラッグ可能なので、JTableHeaderの外部まで列をドラッグしてポップアップメニューを開くと描画が乱れる場合がある
      • JPopupMenu#show(...)メソッドをオーバーライドしてドラッグ中の列をクリア、ヘッダの再描画などを実行して回避する必要がある
    • 列の入れ替えを禁止する場合はtable.getTableHeader().setReorderingAllowed(false);を設定する
  • Disable right mouse button reordering
    • JLayerJTableを配置したJScrollPaneに設定
      • LayerUI#processMouseMotionEvent(...)メソッドをオーバーライドし、JTableHeader上の右ボタンでのドラッグイベントを消費
    • マウスの左、中ボタンでのドラッグは有効
    • マウスの右ボタンをクリックしてJTableHeaderに設定したポップアップメニューを開くことは可能
    • 左ボタンでドラッグ開始、途中で左右両方のボタンを押して右ボタンを後からリリースするとJTableHeaderの外部でポップアップメニューを開くことが可能なので、Defaultと同様にJPopupMenu#show(...)メソッドをオーバーライドしてドラッグ中の列をクリア、ヘッダの再描画などを実行する必要がある

参考リンク

コメント