• category: swing folder: DisableRightButtonFloating title: JToolBarの右マウスボタンでのドラッグアウトを無効にする tags: [JToolBar, JLayer] author: aterai pubdate: 2022-07-11T02:40:01+09:00 description: JToolBarのドラッグアウト開始を左マウスボタンでのみ可能になるよう制限します。 image: https://drive.google.com/uc?id=12XVKQQIGqcIDa8p5FfEPfvHJTTZ9qyMn

概要

JToolBarのドラッグアウト開始を左マウスボタンでのみ可能になるよう制限します。

サンプルコード

class DockingListener2 extends MouseInputAdapter {
  private final JToolBar toolBar;
  private final MouseInputListener listener;

  protected DockingListener2(JToolBar toolBar, MouseInputListener listener) {
    super();
    this.toolBar = toolBar;
    this.listener = listener;
  }

  private boolean cancelDrag(MouseEvent e) {
    return !toolBar.isEnabled() || !SwingUtilities.isLeftMouseButton(e);
  }

  @Override public void mousePressed(MouseEvent e) {
    if (cancelDrag(e)) {
      return;
    }
    listener.mousePressed(e);
  }

  @Override public void mouseDragged(MouseEvent e) {
    if (cancelDrag(e)) {
      return;
    }
    listener.mouseDragged(e);
  }

  @Override public void mouseReleased(MouseEvent e) {
    if (cancelDrag(e)) {
      return;
    }
    listener.mouseReleased(e);
  }
}
View in GitHub: Java, Kotlin

解説

  • Default
    • デフォルトのJToolBarは左マウスボタンだけでなく右・中マウスボタンでもドラッグ・アウトが可能
    • このためWindowsLookAndFeel環境などでJToolBarJPopupMenuを設定して右マウスボタンでドラッグ・アウトするとJToolBarは元の位置に残ったままドラッグ中のJWindowも表示され続ける状態になる
      • 再度左マウスボタンでJToolBarをドラッグ・アウトし直さないとドラッグ中のJWindowを非表示に戻せないバグ?
  • Override createDockingListener()
    • BasicToolBarUI#createDockingListener()をオーバーライドして右マウスボタンでのドラッグ・アウトはキャンセルするよう設定
    • このサンプルではBasicToolBarUIJToolBarに設定しているので、子のJButtonLookAndFeelがデフォルトのJToolBarに配置したJButtonとは異なる描画になっている
  • DisableRightButtonDraggedOut
    • JLayerを使用して右マウスボタンでのドラッグ・アウトはキャンセルするよう設定
    • JToolBarに直接JLayerを設定するとドラッグで配置を変更したときに例外が発生するので、JToolBarの親JPanelJLayerを設定する必要がある
    • このサンプルではJToolBarの名前がDisableRightButtonDraggedOutと一致する場合のみ右マウスボタンでのドラッグ・アウトを無効化している
    • 左マウスボタンでドラッグ・アウトを開始して右マウスボタンをプレス、左マウスボタンをリリース、右マウスボタンをリリースするとデフォルトのJToolBarと同様に非表示化できないドラッグ中のJWindowが生成されてしまう
      class DisableRightButtonDragOutLayerUI extends LayerUI<JPanel> {
        @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 JPanel> l) {
          Component c = e.getComponent();
          if (c instanceof JToolBar) {
            boolean dragEvent = e.getID() == MouseEvent.MOUSE_DRAGGED;
            boolean leftButton = SwingUtilities.isLeftMouseButton(e);
            boolean checkName = "DisableRightButtonDraggedOut".equals(c.getName());
            if (dragEvent && !leftButton && checkName) {
              e.consume();
            }
          }
        }
      }
      

参考リンク

コメント