JDK-4214095 : Need setInitialFocus method for Window Class
  • Type: Enhancement
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.1.6,1.2.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic,solaris_2.5.1
  • CPU: generic,sparc
  • Submitted: 1999-02-23
  • Updated: 2000-10-04
  • Resolved: 2000-10-04
Related Reports
Duplicate :  
Description

Name: dbT83986			Date: 02/23/99


When creating a window there needs to be a method
that will allow one to set the keyboard focus to
any valid component in that window.  requestFocus
does not work until after a window is shown. If a
modal dialog is being shown then there is no way
to set initial focus to a component.

Call something like this:

setInitialFocus (Component comp)
{
    // give component focus when window is shown
}

or setDefaultFocus(comp)?
(Review ID: 42892)
======================================================================

Name: krT82822			Date: 09/26/99


The Dialog class needs a way for the user to specify
which component should receive the initial focus after
a modal dialog has been made visible.

At the moment, the first focusable component gets
the focus. This is not always the desired effect
- sophisticated applications must be able to change
this behaviour. Making sure that the component that
should receive the initial focus is the first one
to be added to the first container of the Dialog
isn't a viable option if you have nested components.

As a result of this, I suggest adding a new method to
the Dialog class: setInitialFocusComponent(Component c).
If this is set to null or not explicitly set, the
default behaviour would be the same as it is now
(e.g. the first focusable component gets the focus).
However, if the user sets this property to a specific
component (that needs to be a descendent of the dialog),
the AWT will make sure that, after the dialog has been
made visible, the specified component will have the focus.

The release of the new JDK1.3 which includes other API
changes too would be a great opportunity to fix this problem.

-- example program below --

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class ModalDialogFocusTest extends JDialog {
  public ModalDialogFocusTest() {
    super((Frame) null, "RFE: Modal Dialog needs setInitialFocusComponent", true);
    
    JPanel pnl = new JPanel();
    pnl.setBorder(new EmptyBorder(12, 12, 12, 12));
    pnl.setLayout(new GridBagLayout());
    
      JLabel nameLbl = new JLabel("Name:");
      pnl.add(nameLbl, new GridBagConstraints(
        0, GridBagConstraints.RELATIVE, 1, 1, 1, 0,
        GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
        new Insets(0, 0, 0, 0), 0, 0));
      
      JTextField nameTf = new JTextField();
      pnl.add(nameTf, new GridBagConstraints(
        0, GridBagConstraints.RELATIVE, 1, 1, 1, 0,
        GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
        new Insets(0, 0, 0, 0), 0, 0));
        
      JLabel attrLbl = new JLabel("Attributes:");
      pnl.add(attrLbl, new GridBagConstraints(
        0, GridBagConstraints.RELATIVE, 1, 1, 1, 0,
        GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
        new Insets(0, 0, 0, 0), 0, 0));
        
      JScrollPane attrScp = new JScrollPane();
      attrScp.setHorizontalScrollBarPolicy(
        JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
      attrScp.setVerticalScrollBarPolicy(
        JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    
        JPanel attrPnl = new JPanel();
        attrPnl.setBackground(Color.cyan);
        attrPnl.setLayout(new GridBagLayout());
    
          JTextField attrTf1 = new JTextField();
          attrPnl.add(attrTf1, new GridBagConstraints(
            GridBagConstraints.RELATIVE, 0, 1, 1, 1, 0,
            GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
            new Insets(0, 2, 0, 2), 0, 0));
            
          JTextField attrTf2 = new JTextField();
          attrTf2.setText("Initial focus needed here.");
          attrPnl.add(attrTf2, new GridBagConstraints(
            GridBagConstraints.RELATIVE, 0, 1, 1, 1, 0,
            GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
            new Insets(0, 2, 0, 2), 0, 0));
            
          JTextField attrTf3 = new JTextField();
          attrPnl.add(attrTf3, new GridBagConstraints(
            GridBagConstraints.RELATIVE, 0, 1, 1, 1, 0,
            GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL,
            new Insets(0, 2, 0, 2), 0, 0));
    
        attrScp.getViewport().add(attrPnl);
      
      pnl.add(attrScp, new GridBagConstraints(
        0, GridBagConstraints.RELATIVE, 1, 1, 1, 1,
        GridBagConstraints.CENTER, GridBagConstraints.BOTH,
        new Insets(0, 0, 0, 0), 0, 0));
      
      JButton okBut = new JButton("OK");
      okBut.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent ev) {
            setVisible(false);
          }
        });
      pnl.add(okBut, new GridBagConstraints(
        0, GridBagConstraints.RELATIVE, 1, 1, 0, 0,
        GridBagConstraints.CENTER, GridBagConstraints.NONE,
        new Insets(8, 8, 8, 8), 0, 0));
    
    getContentPane().add(pnl);
    
    setSize(new Dimension(400, 400));
    setLocation((getToolkit().getScreenSize().width
                - getSize().width) / 2,
                (getToolkit().getScreenSize().height
                - getSize().height) / 2);
                
    final Component initialFocusCmp = attrTf2;
    
    // it should be possible to do the following:
    // setInitialFocusComponent(initialFocusCmp);
      
    setVisible(true);
  }
  
  public static void main(String args[]) {
    new ModalDialogFocusTest();
    System.exit(0);
  }
}
(Review ID: 95739)
======================================================================

Comments
WORK AROUND Name: krT82822 Date: 09/26/99 The only more or less simple, yet ugly, workaround that I know of is to insert the following lines just before the setVisible(true); call: new Thread(new Runnable() { public void run() { do { initialFocusCmp.requestFocus(); try { Thread.sleep(75); } catch (InterruptedException ex) { } } while (!initialFocusCmp.hasFocus()); } }).start(); NOTE: when used with the above example program, this exhibits another bug: sometimes, the caret in the "name" text field is still visible (although it does not blink anymore) after the focus has already been transferred to the "attrTf2" text field. This is very irritating. Is there a bug report that addresses this problem (ID?). (Review ID: 95739) ======================================================================
11-06-2004

EVALUATION Currently planning to implement this functionality, or equivalent functionality, in the merlin focus enhancements. david.mendenhall@eng 1999-12-14
14-12-1999