• category: swing folder: DividerMouseEvent title: JSplitPaneのDividerにJPopupMenuやMouseListenerを追加してその位置を変更する tags: [JSplitPane, Divider, JPopupMenu, MouseListener] author: aterai pubdate: 2021-07-26T02:28:40+09:00 description: JSplitPaneのDividerにJPopupMenuやMouseListenerを追加してその位置を中央、最小、最大位置に変更するためのActionを設定します。 image: https://drive.google.com/uc?id=1JNqfni40ogZAmYoqP76Sw3gg8BvdRMVK

概要

JSplitPaneのDividerにJPopupMenuやMouseListenerを追加してその位置を中央、最小、最大位置に変更するためのActionを設定します。

サンプルコード

JCheckBox check = new JCheckBox("Show JPopupMenu only on Divider", true);
JPopupMenu popup = new JPopupMenu() {
  @Override public void show(Component invoker, int x, int y) {
    if (check.isSelected() && invoker instanceof JSplitPane) {
      BasicSplitPaneUI ui = (BasicSplitPaneUI) ((JSplitPane) invoker).getUI();
      if (ui.getDivider().getBounds().contains(x, y)) {
        super.show(invoker, x, y);
      }
    } else {
      super.show(invoker, x, y);
    }
  }
};
popup.add("center").addActionListener(e -> splitPane.setDividerLocation(.5));
popup.add("selectMin").addActionListener(e -> selectMinMax(splitPane, "selectMin"));
popup.add("selectMax").addActionListener(e -> selectMinMax(splitPane, "selectMax"));
splitPane.setComponentPopupMenu(popup);

BasicSplitPaneUI ui = (BasicSplitPaneUI) splitPane.getUI();
Container divider = ui.getDivider();
divider.addMouseListener(new MouseAdapter() {
  @Override public void mouseClicked(MouseEvent e) {
    if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() >= 2) {
      splitPane.setDividerLocation(.5);
    }
  }

  // @Override public void mouseReleased(MouseEvent e) {
  //   if (e.isPopupTrigger()) {
  //     popup.show(divider, e.getX(), e.getY());
  //   }
  // }
});
View in GitHub: Java, Kotlin

解説

  • JPopupMenu
    • BasicSplitPaneUI#getDivider()で取得可能なBasicSplitPaneDividerJComponentを継承していないため、JComponent#setComponentPopupMenu(...)が使用不可
    • 代わりにBasicLookAndFeel.AWTEventHelper#eventDispatched(...)getParent()で取得した親コンポーネントからJPopupMenuを取得して表示するよう特別処理されている
    • このため上記のサンプルではDividerを右クリックするとその親であるJSplitPaneに設定したJPopupMenuが開く
    • JSplitPaneに設定されたBorder上で右クリックした場合もJSplitPaneに設定したJPopupMenuが開くことになるので、JPopupMenu#show(...)をオーバーライドしてDividerのコンテナ領域がクリックされた場合のみJPopupMenuを開くよう設定(JCheckBoxで切り替えてテスト可能)
  • MouseListener
    • BasicSplitPaneUI#getDivider()で取得可能なBasicSplitPaneDividerContainerを継承するため、Component#addMouseListener(...)MouseListenerが使用可能
    • マウスの左ボタンでダブルクリックするとDividerの位置を中央に移動するMouseListenerを設定
    • たとえばWindows環境だけ考慮する場合、JComponent#setComponentPopupMenu(...)を使用せずにMouseListener#mouseReleased(...)if (e.isPopupTrigger()) { popup.show(divider, e.getX(), e.getY()); }を実行してJPopupMenuを表示する方法もある

参考リンク

コメント