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

JComponent.setNextFocusableComponent doesn't always work as expected

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.2.0
    • 1.1.5, 1.1.6, 1.2.0
    • client-libs
    • 1.2fcs
    • generic, x86, sparc
    • solaris_2.6, windows_nt
    • Not verified



      Name: rk38400 Date: 04/15/98


      [ Note: Re-submitted as instructed, the bug had
        id : 25173 and is still present in the new
        swing-1.0.1 release
      ]

      JComponent.setNextFocusableComponent doesn't always work as expected
      description : If JComponent.setNextFocusableComponent is used
      to explicitly set the "next focus" of a component
      to a component that was added before the Component
      for which the next focus is specified, the focus
      order is messed up and/or a
      java.lang.ArrayIndexOutOfBoundsException can
      happen.

      Example1: Run the program below, place the mouse
      into one of the textfields and press TAB. The
      following exception is thrown (this always happens,
      when the last component of a container has its
      `NextFocusableComponent' specified):

      Exception occurred during event dispatching:
      java.lang.ArrayIndexOutOfBoundsException: 2 > 1
              at java.util.Vector.insertElementAt(Vector.java)
              at com.sun.java.swing.DefaultFocusManager.childrenTabOrder(DefaultFocusManager.java:303)
              at com.sun.java.swing.DefaultFocusManager.getComponentAfter(DefaultFocusManager.java:225)
      ...

      ------------
      import com.sun.java.swing.*;
      import java.awt.*;

      public class focus {
          public static void main(String[] args) {
              JFrame f = new JFrame();
              Container c = f.getContentPane();
              c.setLayout(new BoxLayout(c, BoxLayout.Y_AXIS));
              JTextField tf1 = new JTextField();
              JTextField tf2 = new JTextField();
              c.add(tf1);
              c.add(tf2);

              tf2.setNextFocusableComponent(tf1);

              f.pack();
              f.setVisible(true);
          }
      }
      ------------

      Example 2: This example tries to set the next
      component for textfield #3 to textfield #2.
      Run the program, click into textfield #3 and press
      TAB. The focus moves to textfield #4 instead of
      textfield #2!

      ------------
      import com.sun.java.swing.*;
      import java.awt.*;

      public class focus2 {
          public static void main(String[] args) {
              JFrame f = new JFrame();
              Container c = f.getContentPane();
              c.setLayout(new BoxLayout(c, BoxLayout.Y_AXIS));
              JTextField tf1 = new JTextField(20);
              tf1.setText("Textfield #1");
              JTextField tf2 = new JTextField(20);
              tf2.setText("Textfield #2");
              JTextField tf3 = new JTextField(20);
              tf3.setText("Textfield #3");
              JTextField tf4 = new JTextField(20);
              tf4.setText("Textfield #4");
              c.add(tf1);
              c.add(tf2);
              c.add(tf3);
              c.add(tf4);

              tf3.setNextFocusableComponent(tf2);

              f.pack();
              f.setVisible(true);
          }
      }
      (Review ID: 28024)
      ======================================================================
      mircea@canada 1998-06-22 - more information from ###@###.###

      setNextFocusableComponent is documented in bug ID 4129380
      as being broken and a workaround (fix to DefaultFocusManager) is suggested.
      The fix is incomplete. It does not address the problem that occurs when moving
      from the first component to the last component or vice versa.
      With the fix from 4129380 installed, applications will throw and Exception when
      they encounter the boundary condition.

      This can be solved and the DefaultFocusManager made operable by applying the
      the context diff in the "workaround" to DefaultFocusManager.java

      *** DefaultFocusManager.java-orig Wed Jun 17 17:08:52 1998
      --- DefaultFocusManager.java Wed Jun 17 17:12:01 1998
      ***************
      *** 222,230 ****
                Component orderedChildren[] = childrenTabOrder(aContainer);
                int i,c;
        
      ! for(i=1,c=orderedChildren.length ; i < c ; i++)
                    if(orderedChildren[i] == aComponent)
      ! return orderedChildren[i-1];
                return null;
            }
        
      --- 222,230 ----
                Component orderedChildren[] = childrenTabOrder(aContainer);
                int i,c;
        
      ! for(i=0,c=orderedChildren.length-1; i <= c ; i++)
                    if(orderedChildren[i] == aComponent)
      ! return orderedChildren[(i == 0) ? c : i-1];
                return null;
            }
        
      ***************
      *** 233,241 ****
                Component orderedChildren[] = childrenTabOrder(aContainer);
        
                int i,c;
      ! for(i=0,c=orderedChildren.length - 1; i < c ; i++)
                    if(orderedChildren[i] == aComponent)
      ! return orderedChildren[i+1];
                return null;
            }
        
      --- 233,241 ----
                Component orderedChildren[] = childrenTabOrder(aContainer);
        
                int i,c;
      ! for(i=0,c=orderedChildren.length-1; i <= c ; i++)
                    if(orderedChildren[i] == aComponent)
      ! return orderedChildren[(i == c) ? 0 : i+1];
                return null;
            }
        
      ***************
      *** 309,320 ****
                           (nextComponent = ((JComponent)children[i]).getNextFocusableComponent()) != null) {
                            if((index = v.indexOf(nextComponent)) != -1) {
                                v.removeElementAt(index);
      ! v.insertElementAt(nextComponent,i+1);
                            }
                        }
                    }
        
      ! for(i=0 ; i < c ; i++)
                        children[i] = (Component) v.elementAt(i);
                }
        
      --- 309,320 ----
                           (nextComponent = ((JComponent)children[i]).getNextFocusableComponent()) != null) {
                            if((index = v.indexOf(nextComponent)) != -1) {
                                v.removeElementAt(index);
      ! v.insertElementAt(nextComponent,i+((index > i) ? 1 : 0));
                            }
                        }
                    }
        
      ! for(i=0 ; i < c ; i++)
                        children[i] = (Component) v.elementAt(i);
                }

            hgajewsksunw Hania Gajewska (Inactive)
            rkarsunw Ralph Kar (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: