---
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
---
* 概要 [#summary]
`JLayer`を使用して`JTableHeader`の列をマウスの右ボタンでドラッグしても順序変更不可に設定します。

#download(https://drive.google.com/uc?id=1fETWKkk9g8-SRVPtWT7UmZhoBEue-8rK)

* サンプルコード [#sourcecode]
#code(link){{
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();
    }
  }
}
}}

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

- `Default`
-- 右ボタンでドラッグ可能なので、`JTableHeader`の外部まで列をドラッグしてポップアップメニューを開くと描画が乱れる場合がある
--- `JPopupMenu#show(...)`メソッドをオーバーライドしてドラッグ中の列をクリア、ヘッダの再描画などを実行して回避する必要がある
-- 列の入れ替えを禁止する場合は`table.getTableHeader().setReorderingAllowed(false);`を設定する
--- [[JTableのヘッダ入れ替えを禁止>Swing/Reordering]]
- `Disable right mouse button reordering`
-- `JLayer`を`JTable`を配置した`JScrollPane`に設定
--- `LayerUI#processMouseMotionEvent(...)`メソッドをオーバーライドし、`JTableHeader`上の右ボタンでのドラッグイベントを消費
-- マウスの左、中ボタンでのドラッグは有効
-- マウスの右ボタンをクリックして`JTableHeader`に設定したポップアップメニューを開くことは可能
-- 左ボタンでドラッグ開始、途中で左右両方のボタンを押して右ボタンを後からリリースすると`JTableHeader`の外部でポップアップメニューを開くことが可能なので、`Default`と同様に`JPopupMenu#show(...)`メソッドをオーバーライドしてドラッグ中の列をクリア、ヘッダの再描画などを実行する必要がある
-- [https://bugs.openjdk.org/browse/JDK-8068824 &#91;JDK-8068824&#93; Exception thrown in JTableHeader after clicking on popupmenu opened with right-click on header - Java Bug System]

* 参考リンク [#reference]
- [[JTableのヘッダ入れ替えを禁止>Swing/Reordering]]
- [[JTableHeaderに追加された各TableColumnの表示・非表示を切り替える>Swing/AddRemoveTableColumn]]
- [[JComboBoxのドロップダウンリストで右クリックを無効化>Swing/DisableRightClick]]
-- こちらのサンプル同様、`WindowsLookAndFeel`でのみ右ボタンドラッグを無効にしても良いかもしれない
- [[JToolBarの右マウスボタンでのドラッグアウトを無効にする>Swing/DisableRightButtonFloating]]
- [https://bugs.openjdk.org/browse/JDK-8068824 &#91;JDK-8068824&#93; Exception thrown in JTableHeader after clicking on popupmenu opened with right-click on header - Java Bug System]

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