Swing/DraggablePopupMenu の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/DraggablePopupMenu へ行く。
- Swing/DraggablePopupMenu の差分を削除
--- category: swing folder: DraggablePopupMenu title: JPopupMenuにマウスドラッグで位置変更を可能にするヘッダを追加する tags: [JPopupMenu, MouseListener, JLabel, JWindow] author: aterai pubdate: 2022-10-31T00:03:07+09:00 description: JPopupMenuにJLabelで作成したヘッダを追加し、MouseListenerを追加してドラッグで位置変更を可能にします。 image: https://drive.google.com/uc?id=1bT2wG0hF2SSjNYBY5t23Xl-8_WCRHdPO hreflang: href: https://java-swing-tips.blogspot.com/2022/10/add-header-to-jpopupmenu-to-enable.html lang: en --- * 概要 [#summary] `JPopupMenu`に`JLabel`で作成したヘッダを追加し、`MouseListener`を追加してドラッグで位置変更を可能にします。 #download(https://drive.google.com/uc?id=1bT2wG0hF2SSjNYBY5t23Xl-8_WCRHdPO) * サンプルコード [#sourcecode] #code(link){{ class PopupHeaderMouseListener extends MouseAdapter { private final Point startPt = new Point(); @Override public void mousePressed(MouseEvent e) { if (SwingUtilities.isLeftMouseButton(e)) { startPt.setLocation(e.getPoint()); } } @Override public void mouseDragged(MouseEvent e) { Component c = e.getComponent(); Window w = SwingUtilities.getWindowAncestor(c); if (w != null && SwingUtilities.isLeftMouseButton(e)) { if (w.getType() == Window.Type.POPUP) { // Popup$HeavyWeightWindow Point pt = e.getLocationOnScreen(); w.setLocation(pt.x - startPt.x, pt.y - startPt.y); } else { // Popup$LightWeightWindow Container popup = SwingUtilities.getAncestorOfClass( JPopupMenu.class, c); Point pt = popup.getLocation(); popup.setLocation( pt.x - startPt.x + e.getX(), pt.y - startPt.y + e.getY()); pt.x - startPt.x + e.getX(), pt.y - startPt.y + e.getY()); } } } } }} * 解説 [#explanation] - `JPopupMenu`のデフォルトレイアウトは垂直`BoxLayout`なので、ドラッグ可能なヘッダとして使用する`JLabel`は`getMaximumSize()`をオーバーライドして最大幅を`JPopupMenu`の推奨幅以上に設定しておく -- `JPopupMenu`の幅スペースを残さないようヘッダの幅が水平方向に引き伸ばすために必要な設定 -- [[JComboBoxのドロップダウンリストにヘッダ・フッタを追加する>Swing/HeaderFooterComboPopup]] -- `GTKLookAndFeel`では`header.setAlignmentX(Component.CENTER_ALIGNMENT)`を設定しないとヘッダ左側に余白が生成される場合がある? - `JPopupMenu`が親`JFrame`外に表示されて`Popup$HeavyWeightWindow`になる場合: -- `MouseEvent#getLocationOnScreen()`で取得したデスクトップ領域の絶対位置に`SwingUtilities.getWindowAncestor(header)`で取得した`JPopupMenu`の親`Window`を移動 -- [[JWindowをマウスで移動>Swing/DragWindow]] - `JPopupMenu`が親`JFrame`内に表示されて`Popup$LightWeightWindow`になる場合: -- `SwingUtilities.getAncestorOfClass(JPopupMenu.class, header)`で取得した`JPopupMenu`の位置を変更 -- [[JComboBoxのドロップダウンリストの高さをマウスドラッグで変更する>Swing/DropDownHeightResizing]] * 参考リンク [#reference] - [[JComboBoxのドロップダウンリストにヘッダ・フッタを追加する>Swing/HeaderFooterComboPopup]] - [[JToggleButtonからポップアップメニューを開く>Swing/ToolButtonPopup]] - [[JComboBoxのドロップダウンリストの高さをマウスドラッグで変更する>Swing/DropDownHeightResizing]] - [[JWindowをマウスで移動>Swing/DragWindow]] * コメント [#comment] #comment #comment