JDK-6449862 : During intialization focus lost for JTextField in Solaris
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 5.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_9
  • CPU: sparc
  • Submitted: 2006-07-18
  • Updated: 2011-02-16
  • Resolved: 2006-07-26
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
jre_1.5.0.06

ADDITIONAL OS VERSION INFORMATION :
SunOS omea2 5.9 Generic_118558-25 sun4u sparc SUNW,Sun-Fire-280R

A DESCRIPTION OF THE PROBLEM :
The Login Dialog consist of user ID and Password as text fields and JOptionPane is used to add OK and Cancle button. As soon as Dialog launches in windows the focus is at User ID text field, however in solaris the focus is at OK button. Please find the code snippet for the same :
1. LoginDialog.java - constructs user ID and Password text fields
2. Login.java - Display the Dialog

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
With the above java files launch the GUI and observe that focus is at OK button in solaris machine.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Focus should be at user ID text field as in windows(Even for solaris in jre1.4.2 the focus was at user ID text field on in jre1.5 problem is occuring)
ACTUAL -
Focus is not at user ID text field

---------- BEGIN SOURCE ----------
************************************************************
1. LoginDialog.java

class LoginDialog extends JPanel {
    private JLabel serverLabel = null;
    private JLabel userIdLabel = new JLabel("User ID:");
    protected JTextField userIdField = null;

    private JLabel passwdLabel = new JLabel("Password:");
    protected JPasswordField passwdField = new JPasswordField();

    // constructor
    LoginDialog(String userID, String ipAddress) {
    	userIdField = new JTextField(){
        	public void requestFocus() {
                Thread.dumpStack();
                super.requestFocus();
                }
            };
        setSize(460, 270);
        setLayout(new BorderLayout());
        serverLabel = new JLabel("Login to server: " + ipAddress);
        userIdField.setPreferredSize(new Dimension(100, 21));
        userIdField.setEditable(true);
        passwdField.setPreferredSize(new Dimension(100, 21));
        passwdField.setEditable(true);
        userIdField.addFocusListener(new UserIdFocusListener());
        

        if ((userID != null) && (userID.length() > 0)) {
            userIdField.setText(userID);
        }

        // set the components
        JPanel panel = new JPanel();
        GridBagLayout gb = new GridBagLayout();
        GridBagConstraints gbc = new GridBagConstraints();
        panel.setLayout(gb);
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(3, 0, 1, 0);
        gb.setConstraints(serverLabel, gbc);
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.insets = new Insets(3, 0, 1, 0);
        gb.setConstraints(userIdLabel, gbc);
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.insets = new Insets(3, 0, 1, 0);
        gbc.anchor = GridBagConstraints.WEST;
        gb.setConstraints(userIdField, gbc);
        gbc.gridx = 0;
        gbc.gridy = 2;
        gb.setConstraints(passwdLabel, gbc);
        gbc.gridx = 1;
        gbc.gridy = 2;
        gb.setConstraints(passwdField, gbc);
        panel.add(userIdLabel);
        panel.add(userIdField);
        panel.add(passwdLabel);
        panel.add(passwdField);

        // add the splash image
        URL fileUrl = getClass().getResource("LoginSplash.gif");
        ImageIcon img = new ImageIcon(fileUrl);
        Image splashImg = img.getImage();

        add(new JLabel(img), BorderLayout.NORTH);
        add(serverLabel, BorderLayout.CENTER);
        add(panel, BorderLayout.SOUTH);
       // userIdField.requestFocus();
//      WORKAROUND for all releases
        setFocusCycleRoot(true);
        setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
                public Component getDefaultComponent(Container cont) {
                    return userIdField;
                }
            });

    }
  .....
}

************************
2. Login.java
public class Login{
  ......
   private void displayLogin(String oldUserID) {
        LoginDialog loginDialog = new LoginDialog(oldUserID, ipAddress);

        JOptionPane pane = new JOptionPane(loginDialog);
        pane.setOptionType(JOptionPane.OK_CANCEL_OPTION);

        JDialog dialog = pane.createDialog(mainFrame, "Login to " + ipAddress);
        loginDialog.userIdField.requestFocus();
        dialog.show();
        .....
   }
 ......
}

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

REPRODUCIBILITY :
This bug can be reproduced always.

Comments
WORK AROUND To have the JTextField focused, show the dialog on a new thread and then, when it's shown (you have to synchronized this), request focus on the JTextField.
26-07-2006

EVALUATION Actually, that what focus appears on JTextField is wrong. Indeed, focus is requested on this component, but before the dialog is shown. However when the dialog is being shown JOptionPane requests focus on its initial component ('selectInitialValue' method). Thus the JTextField should gain focus first and then the "OK" button takes it. This is correct behaviour. And this is the case since Mustang b79 on Windows. It's the fix for CR 6382750 that corrects the things. The fix removes unexpected FOCUS_GAINED coming to a dialog when it's shown. This event disrupted focus events order and leaded to that the JTextField received focus after the "OK" button. So, I'm closing this as a duplicate.
26-07-2006

EVALUATION reassigned to AWT
21-07-2006