One of our customer reported an exception in our application. The problem is, I am completely unable to understand how this bug can be reproduced.
Here is the code :
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
popup.show(btn, 3, btn.getHeight());
}
});
Notes :
btnis a final local variable of typeJButton.popupis a final local variable of typeJPopupMenu.
The following exception was thrown :
java.awt.IllegalComponentStateException: component must be showing on the screen to determine its location
at java.awt.Component.getLocationOnScreen_NoTreeLock(Unknown Source)
at java.awt.Component.getLocationOnScreen(Unknown Source)
at javax.swing.JPopupMenu.show(Unknown Source)
at fr.def.iss.vd2.mod_site_watcher_gui.SiteElementPanel$4.actionPerformed(SiteElementPanel.java:117)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.focusLost(Unknown Source)
at java.awt.Component.processFocusEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$000(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.awt.EventQueue$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.awt.EventQueue$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
As far as I understand, the show method complains that btn is not showing. How is it possible that btn is not showing when its actionPerformed method is called ?
The strangest thing in this stacktrace is that the actionPerformed method seems to be triggered while a FocusEvent is being handled (a focusLost, actually).
The question is : can you explain how this stacktrace can possibly happen ?
Epilogue
Thanks to a suggestion from trashgod, I found the problem.
On Windows, when a button disappears while it is being pressed, then its ActionListeners are triggered, as if the button was clicked. This behavior can be observed on Windows, but not on Linux.
I filed a bug on the Oracle/Sun bug database. here is the link :
https://bugs.java.com/bugdatabase/view_bug?bug_id=7115421
(this link will become valid whithin a few days, after it is reviewed by the Java team).
Thanks for your help. The answers from trashgod and Thomas helped a lot.
One possible source is a race condition that allows an event to fire before the recipient is visible. Verify that your Swing GUI objects are constructed and manuipulated only on the event dispatch thread. The article Debugging Swing, the final summary cited in How to generate exceptions from RepaintManager mentions several approaches to automating the search.