It seems like focus is given to the JRootPane
whenever a JPopupMenu
is shown. You can listen for this event by using a KeyboardFocusManager
:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.beans.*;
public class PopupListener extends JPanel
{
JPopupMenu menu;
public PopupListener()
{
menu = new JPopupMenu();
menu.add( new JMenuItem( "Cut" ) );
menu.add( new JMenuItem( "Copy" ) );
menu.add( new JMenuItem( "Paste" ) );
MouseListener ml = new MouseAdapter()
{
public void mouseReleased(MouseEvent e)
{
if (e.isPopupTrigger())
{
menu.show(e.getComponent(), e.getX(), e.getY());
menu.setInvoker( e.getComponent() );
}
}
};
addMouseListener( ml );
JButton button = new JButton( "Button" );
button.setComponentPopupMenu( menu );
//button.addMouseListener( ml );
add(button);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("PopupListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new PopupListener());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setLocationByPlatform( true );
frame.setVisible( true );
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addPropertyChangeListener("focusOwner", new PropertyChangeListener()
{
public void propertyChange(final PropertyChangeEvent e)
{
Container container = (Container)e.getNewValue();
if (container != null
&& container instanceof JRootPane)
{
System.out.println( "Popup Shown" );
}
}
});
}
public static void main(String[] args)
{
java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
}
}
Don't know if this is the only event that will give focus to the root pane.
So, a more complete check might be to see if a JPopupMenu
component has been added to the JRootPane
.
This can be done by using the Swing Utils class and replacing the above edit with:
if (container != null
&& SwingUtils.getDescendantsOfType(JPopupMenu.class, container, true).size() != 0)
{
System.out.println( "JPopupMenu found" );
}