Smajl
Smajl

Reputation: 7995

Swing popup menu on a component and its content

I have a component (Widget - extends a JPanel) on which I have implemented a simple popup menu. It works when clicking on the border of the panel and basically everywhere except for the places where the panel layout contains some other component inside the panel.

So if there is a JTable inside the panel, I can invoke the menu when clicking next to it (if there is nothing else) but when clicking on the JTable, nothing happens (the table is obviously on top of the panel preventing the MouseAdapter to register the click).

Can I somehow make the popup menu invoked when right clicking even on the components inside the panel? Here is the sample code how I create and invoke the menu:

private void initPopupMenu() {
        popup = new JPopupMenu();

        JMenuItem closeItem = new JMenuItem("Close");
        closeItem.setActionCommand(WidgetConstants.Actions.CLOSE.name());
        closeItem.addActionListener(this);
        popup.add(closeItem);

        JMenuItem minimizeItem = new JMenuItem("Minimize");
        minimizeItem.setActionCommand(WidgetConstants.Actions.MINIMIZE.name());
        minimizeItem.addActionListener(this);
        popup.add(minimizeItem);
    }

MouseInputListener componentListener = new MouseInputAdapter() {

        @Override
        public void mousePressed(MouseEvent me) {
            // popup
            if (me.isPopupTrigger()) {
                popup.show(me.getComponent(), me.getX(), me.getY());
            }
        }

        @Override
        public void mouseReleased(MouseEvent ev) {
            if (ev.isPopupTrigger()) {
                popup.show(ev.getComponent(), ev.getX(), ev.getY());
            }
        }
}

@Override
public void setBorder(Border border) {
        removeMouseListener(componentListener);
        removeMouseMotionListener(componentListener);
        if (border instanceof WidgetBorder) {
            addMouseListener(componentListener);
            addMouseMotionListener(componentListener);
        }
        super.setBorder(border);
    }

Thank you for any tips.

Upvotes: 1

Views: 2155

Answers (1)

Sergiy Medvynskyy
Sergiy Medvynskyy

Reputation: 11327

First of all: you don't need to use a mouse listener. Each JComponent has the method setComponentPopupMenu(JPopupMenu). Secon: you can traverse the component tree an register the popup menu for each component.

Here is example:

/**
 * Provides component hierarchy traversal.
 *
 * @param aContainer start node for the traversal.
 */
private void traverse(Container aContainer, JPopupMenu aMenu) {
    for (final Component comp : aContainer.getComponents()) {
        if (comp instanceof JComponent) {
            ((JComponent) comp).setComponentPopupMenu(aMenu);
        }
        if (comp instanceof Container) {
            traverse((Container) comp, aMenu);
        }
    }
}

Upvotes: 4

Related Questions