Swing/DividerMouseEvent の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/DividerMouseEvent へ行く。
- Swing/DividerMouseEvent の差分を削除
--- 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 --- * 概要 [#summary] `JSplitPane`の`Divider`に`JPopupMenu`や`MouseListener`を追加してその位置を中央、最小、最大位置に変更するための`Action`を設定します。 #download(https://drive.google.com/uc?id=1JNqfni40ogZAmYoqP76Sw3gg8BvdRMVK) * サンプルコード [#sourcecode] #code(link){{ 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")); 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()); // } // } }); }} * 解説 [#explanation] - `JPopupMenu` -- `BasicSplitPaneUI#getDivider()`で取得可能な`BasicSplitPaneDivider`は`JComponent`を継承していないため、`JComponent#setComponentPopupMenu(...)`が使用不可 -- 代わりに`BasicLookAndFeel.AWTEventHelper#eventDispatched(...)`で`getParent()`で取得した親コンポーネントから`JPopupMenu`を取得して表示するよう特別処理されている -- このため上記のサンプルでは`Divider`を右クリックするとその親である`JSplitPane`に設定した`JPopupMenu`が開く -- `JSplitPane`に設定された`Border`上で右クリックした場合も`JSplitPane`に設定した`JPopupMenu`が開くことになるので、`JPopupMenu#show(...)`をオーバーライドして`Divider`のコンテナ領域がクリックされた場合のみ`JPopupMenu`を開くよう設定(`JCheckBox`で切り替えてテスト可能) - `MouseListener` -- `BasicSplitPaneUI#getDivider()`で取得可能な`BasicSplitPaneDivider`は`Container`を継承するため、`Component#addMouseListener(...)`で`MouseListener`が使用可能 -- マウスの左ボタンでダブルクリックすると`Divider`の位置を中央に移動する`MouseListener`を設定 -- たとえば`Windows`環境だけ考慮すればよい場合、`JComponent#setComponentPopupMenu(...)`を使用せずに`MouseListener#mouseReleased(...)`で`if (e.isPopupTrigger()) { popup.show(divider, e.getX(), e.getY()); }`を実行して`JPopupMenu`を表示する方法もある * 参考リンク [#reference] - [[JSplitPaneを等分割する>Swing/DividerLocation]] - [[JSplitPaneの収納状態を維持する>Swing/KeepHiddenDivider]] * コメント [#comment] #comment #comment