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

TAB navigation between radiobuttons will cause IllegalArgumentException

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P3
    • Resolution: Duplicate
    • Affects Version/s: 8u40
    • Fix Version/s: None
    • Component/s: client-libs
    • Labels:

      Description

      FULL PRODUCT VERSION :
      java version "1.8.0_40"
      Java(TM) SE Runtime Environment (build 1.8.0_40-b26)
      Java HotSpot(TM) 64-Bit Server VM (build 25.40-b25, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Windows 7 Enterprise, Service Pack 1

      A DESCRIPTION OF THE PROBLEM :
      Using TAB to navigate to next radiobutton in buttongroup will cause:

      java.lang.IllegalArgumentException: aContainer is not a focus cycle root of aComponent

      When using WindowsLookAndFeel via:

      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

      The NimbusLookAndFeel handles this without problem. Other look and feels also will produce this problem.





      REGRESSION. Last worked in version 8u31

      ADDITIONAL REGRESSION INFORMATION:
      java version "1.8.0_31"
      Java(TM) SE Runtime Environment (build 1.8.0_31-b13)
      Java HotSpot(TM) 64-Bit Server VM (build 25.31-b07, mixed mode)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      We have a JFrame containing a JDesktopPane.

      We add a JInternalFrame, holding a ButtonGroup with three JRadioButtons, to the JDesktopPane.

      When using TAB to navigate to next button we get:

      Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: aContainer is not a focus cycle root of aComponent

      In the case we use WindowsLookAndFeel via:

      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

      The NimbusLookAndFeel handles this without problem. Other look and feels also will produce this problem.

      Se source code for executable example.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The next radio button should gain focus.
      ACTUAL -
      java.lang.IllegalArgumentException: aContainer is not a focus cycle root of aComponent

      No navigation is executed.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: aContainer is not a focus cycle root of aComponent
      at javax.swing.SortingFocusTraversalPolicy.getComponentAfter(SortingFocusTraversalPolicy.java:305)
      at javax.swing.LayoutFocusTraversalPolicy.getComponentAfter(LayoutFocusTraversalPolicy.java:106)
      at javax.swing.plaf.basic.BasicRadioButtonUI$ButtonGroupInfo.getFocusTransferBaseComponent(BasicRadioButtonUI.java:444)
      at javax.swing.plaf.basic.BasicRadioButtonUI$ButtonGroupInfo.jumpToNextComponent(BasicRadioButtonUI.java:567)
      at javax.swing.plaf.basic.BasicRadioButtonUI$KeyHandler.keyPressed(BasicRadioButtonUI.java:597)
      at java.awt.Component.processKeyEvent(Component.java:6483)
      at javax.swing.JComponent.processKeyEvent(JComponent.java:2832)
      at java.awt.Component.processEvent(Component.java:6302)
      at java.awt.Container.processEvent(Container.java:2234)
      at java.awt.Component.dispatchEventImpl(Component.java:4881)
      at java.awt.Container.dispatchEventImpl(Container.java:2292)
      at java.awt.Component.dispatchEvent(Component.java:4703)
      at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1954)
      at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:806)
      at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1074)
      at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:945)
      at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:771)
      at java.awt.Component.dispatchEventImpl(Component.java:4752)
      at java.awt.Container.dispatchEventImpl(Container.java:2292)
      at java.awt.Window.dispatchEventImpl(Window.java:2750)
      at java.awt.Component.dispatchEvent(Component.java:4703)
      at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:751)
      at java.awt.EventQueue.access$500(EventQueue.java:97)
      at java.awt.EventQueue$3.run(EventQueue.java:702)
      at java.awt.EventQueue$3.run(EventQueue.java:696)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
      at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
      at java.awt.EventQueue$4.run(EventQueue.java:724)
      at java.awt.EventQueue$4.run(EventQueue.java:722)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:721)
      at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
      at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
      at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.beans.PropertyVetoException;
      import java.util.logging.Level;
      import java.util.logging.Logger;
      import javax.swing.UIManager;
      import javax.swing.UnsupportedLookAndFeelException;

      public class MainForm extends javax.swing.JFrame {
          
          public MainForm() {
              initComponents();
              createFrame();
          }
          
         private void createFrame() {
              try {
                 
                  ButtonsInternalFrame frame = new ButtonsInternalFrame();
                  frame.setVisible(true);
                  frame.setSelected(true);
                  jDesktopPane1.add(frame);
                  jDesktopPane1.setVisible(true);
              
              } catch (PropertyVetoException ex) {
                  Logger.getLogger(MainForm.class.getName()).log(Level.SEVERE, null, ex);
              }
            
          }

          @SuppressWarnings("unchecked")
          // <editor-fold defaultstate="collapsed" desc="Generated Code">
          private void initComponents() {

              jDesktopPane1 = new javax.swing.JDesktopPane();

              setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

              jDesktopPane1.setBackground(new java.awt.Color(204, 204, 204));

              javax.swing.GroupLayout jDesktopPane1Layout = new javax.swing.GroupLayout(jDesktopPane1);
              jDesktopPane1.setLayout(jDesktopPane1Layout);
              jDesktopPane1Layout.setHorizontalGroup(
                  jDesktopPane1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addGap(0, 400, Short.MAX_VALUE)
              );
              jDesktopPane1Layout.setVerticalGroup(
                  jDesktopPane1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addGap(0, 304, Short.MAX_VALUE)
              );

              javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
              getContentPane().setLayout(layout);
              layout.setHorizontalGroup(
                  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addComponent(jDesktopPane1, javax.swing.GroupLayout.Alignment.TRAILING)
              );
              layout.setVerticalGroup(
                  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addComponent(jDesktopPane1)
              );

              pack();
          }// </editor-fold>
          public static void main(String args[]) throws ClassNotFoundException, IllegalAccessException, InstantiationException, UnsupportedLookAndFeelException {
       
      /*
              try {
                  
                  UIManager.LookAndFeelInfo[] lfInfo = javax.swing.UIManager.getInstalledLookAndFeels();
                  
                  for (javax.swing.UIManager.LookAndFeelInfo info : lfInfo) {
                      if ("Nimbus".equals(info.getName())) {
                          javax.swing.UIManager.setLookAndFeel(info.getClassName());
                          break;
                      }
                  }
              } catch (ClassNotFoundException ex) {
                  java.util.logging.Logger.getLogger(MainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
              } catch (InstantiationException ex) {
                  java.util.logging.Logger.getLogger(MainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
              } catch (IllegalAccessException ex) {
                  java.util.logging.Logger.getLogger(MainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
              } catch (javax.swing.UnsupportedLookAndFeelException ex) {
                  java.util.logging.Logger.getLogger(MainForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
              }
      */
             UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
             System.out.println(System.getProperty("java.version"));

             java.awt.EventQueue.invokeLater(new Runnable() {
                  public void run() {
                      new MainForm().setVisible(true);
                  }
              });
          }
          // Variables declaration - do not modify
          private javax.swing.JDesktopPane jDesktopPane1;
          // End of variables declaration
      }
      public class ButtonsInternalFrame extends javax.swing.JInternalFrame {

          public ButtonsInternalFrame() {
              initComponents();
              jPanel1.setVisible(true);
          }

          @SuppressWarnings("unchecked")
          // <editor-fold defaultstate="collapsed" desc="Generated Code">
          private void initComponents() {

              buttonGroup1 = new javax.swing.ButtonGroup();
              jPanel1 = new javax.swing.JPanel();
              jRadioButton1 = new javax.swing.JRadioButton();
              jRadioButton2 = new javax.swing.JRadioButton();
              jRadioButton3 = new javax.swing.JRadioButton();

              setTitle("Internal frame");

              buttonGroup1.add(jRadioButton1);
              jRadioButton1.setText("First");

              buttonGroup1.add(jRadioButton2);
              jRadioButton2.setText("Second");

              buttonGroup1.add(jRadioButton3);
              jRadioButton3.setText("Third");
              jRadioButton3.setToolTipText("");

              javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
              jPanel1.setLayout(jPanel1Layout);
              jPanel1Layout.setHorizontalGroup(
                  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addGroup(jPanel1Layout.createSequentialGroup()
                      .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                          .addComponent(jRadioButton1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                          .addGroup(jPanel1Layout.createSequentialGroup()
                              .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                  .addComponent(jRadioButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 543, javax.swing.GroupLayout.PREFERRED_SIZE)
                                  .addComponent(jRadioButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE))
                              .addGap(0, 184, Short.MAX_VALUE)))
                      .addContainerGap())
              );
              jPanel1Layout.setVerticalGroup(
                  jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addGroup(jPanel1Layout.createSequentialGroup()
                      .addGap(15, 15, 15)
                      .addComponent(jRadioButton1)
                      .addGap(18, 18, 18)
                      .addComponent(jRadioButton2)
                      .addGap(18, 18, 18)
                      .addComponent(jRadioButton3)
                      .addContainerGap(169, Short.MAX_VALUE))
              );

              javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
              getContentPane().setLayout(layout);
              layout.setHorizontalGroup(
                  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addGroup(layout.createSequentialGroup()
                      .addContainerGap()
                      .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                      .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
              );
              layout.setVerticalGroup(
                  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                      .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                      .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                      .addContainerGap())
              );

              pack();
          }// </editor-fold>

          // Variables declaration - do not modify
          private javax.swing.ButtonGroup buttonGroup1;
          private javax.swing.JPanel jPanel1;
          private javax.swing.JRadioButton jRadioButton1;
          private javax.swing.JRadioButton jRadioButton2;
          private javax.swing.JRadioButton jRadioButton3;
          // End of variables declaration
      }

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

      CUSTOMER SUBMITTED WORKAROUND :
      Currently we have no workaround for using TAB to navigate, the user is forced to use mouse to navigate to next radiobutton.

      This will not stop development but will inconsistent behavior to end user.

      Could this one be causing:

      http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8033699

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              van Vivi An (Inactive)
              Reporter:
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: