Below is a complete compiling running failing example illustrating my question. JMenuItem extends JComponent. When added to JPopupMenu and shown in a context menu... it is... well... SHOWN, but the componentShown method is not called. How can I know when the JMenuItem is shown? I need to know from within the JMenuItem itself. I'm creating this JMenuItem and handing it off to a larger framework. I have no knowledge or control of the JPopupMenu, container, or any other components. When my JMenuItem is shown, I must update its text based on the context and current state of the app. How do I know when it is shown?
In the following example, the text "component shown" is never printed under any circumstances. Right click inside the JPanel to get the context menu and you'll see the JMenuItem text, "Reply Hi", but now output to the console.
I'm running on macOS 11.5.2 Big Sur and JDK 11.0.6 LTS (from Oracle).
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class JMenuItemListeners {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.setMinimumSize(new Dimension(800, 600));
panel.setLayout(new BorderLayout());
panel.add(new JLabel("Hello World... right click me."),
BorderLayout.CENTER);
//========================================
JPopupMenu popupMenu = new JPopupMenu();
JMenuItem menuItem = new JMenuItem("Reply Hi");
menuItem.addComponentListener(
new ComponentListener() {
@Override
public void componentResized(ComponentEvent e) {}
@Override
public void componentMoved(ComponentEvent e) {}
@Override
public void componentShown(ComponentEvent e) {
System.out.println("component shown");
}
@Override
public void componentHidden(ComponentEvent e) {}
}
);
popupMenu.add(menuItem);
panel.setComponentPopupMenu(popupMenu);
//========================================
frame.setContentPane(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}