Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8322754

click JComboBox when dialog about to close causes IllegalComponentStateException

    XMLWordPrintable

Details

    • b05
    • generic
    • generic

    Description

      A DESCRIPTION OF THE PROBLEM :
      Clicking to open a JComboBox popup during AWT event processing at the end of which the dialog will be closed causes an IllegalComponentStateException. This is a re-reporting of 4773491 which I reported over 20 years ago. The evaluation there "Not common usage. Not a feature. This seesm [sic] to be timing related." makes no sense. It can not take zero time to process an event, and there is always some chance the user will click on a combo box during that time. I made that argument then but it was ignored. The very similar bug 4942216 was fixed, and the fix here is the same, check to make sure the combo box is showing before showing the popup, possibly in BasicComboPopup.togglePopup(). We have been receiving these crashes for the last 21 years. We have worked-around for our combo boxes, but we have no control over the ones in JFileChoosers, and we still get crashes for those.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run code.
      Click "Close" button on the dialog.
      Before the dialog closes (2 seconds) click the combo box arrow at the top.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Expect no exceptions.
      ACTUAL -
      Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: component must be showing on the screen to determine its location
      at java.desktop/java.awt.Component.getLocationOnScreen_NoTreeLock(Component.java:2113)
      at java.desktop/java.awt.Component.getLocationOnScreen(Component.java:2087)
      at java.desktop/javax.swing.JPopupMenu.show(JPopupMenu.java:982)
      at java.desktop/javax.swing.plaf.basic.BasicComboPopup.show(BasicComboPopup.java:235)
      at java.desktop/javax.swing.plaf.basic.BasicComboPopup.togglePopup(BasicComboPopup.java:1265)
      at java.desktop/javax.swing.plaf.basic.BasicComboPopup$Handler.mousePressed(BasicComboPopup.java:936)
      at java.desktop/java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:288)
      at java.desktop/java.awt.Component.processMouseEvent(Component.java:6618)
      at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3398)
      at java.desktop/java.awt.Component.processEvent(Component.java:6386)
      at java.desktop/java.awt.Container.processEvent(Container.java:2266)
      at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4996)
      at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
      at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
      at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
      at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4572)
      at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
      at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
      at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
      at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
      at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
      at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
      at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
      at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
      at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
      at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:98)
      at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
      at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
      at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
      at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
      at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
      at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
      at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
      at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
      at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
      at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
      at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)


      ---------- BEGIN SOURCE ----------
      import javax.swing.*;
      import java.awt.*;

      public class JComboBoxBug5 {

         public static void main(String args[]) {
            SwingUtilities.invokeLater(()->go());
         }
         
         public static void go() {
            JDialog dialog = new JDialog();
            JComboBox cb = new JComboBox();
            cb.setEditable(true);
            cb.addItem("test");
            cb.addItem("test2");
            cb.addItem("test3");
            dialog.getContentPane().add(cb, "North");
            JButton b = new JButton("Close");
            b.addActionListener(
               (e)->{
                  try {
                     Thread.sleep(2000);
                  }
                  catch (Exception ex) {
                  }
                  dialog.setVisible(false);
               });
            dialog.getContentPane().add(b, "South");
            dialog.setMinimumSize(new java.awt.Dimension(500, 500));
            dialog.pack();
            dialog.setVisible(true);
         }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Override getLocationOnScreen in a JComboBox subclass as follows:
                  public Point getLocationOnScreen() {
                     try {
                        return super.getLocationOnScreen();
                     }
                     catch (IllegalComponentStateException e) {
                        return new Point(0, 0);
                     }
                  }
      The popup will not be shown, so returning (0,0) does not cause a problem.

      FREQUENCY : always


      Attachments

        Issue Links

          Activity

            People

              psadhukhan Prasanta Sadhukhan
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: