简体   繁体   中英

Focus on component when a panel is loaded

I have a frame, where i load a panel into. It works fine, but nothing has focus when it loads. Pressing tab doesn't help. I have to use the mouse to press a textfield. I've tried: jtextfield1.requestFocus(); and jtextfiel1.requestFocusInWindow(); But it doesn't work.

What am I doing wrong?

The constructor in the JPanel :

public OpretOpdater(BrugerHandler brugerHandler, ReklamationHandler reklamationsHandler) {
    initComponents();
    jTextFieldOrdnr.requestFocusInWindow();
    this.brugerHandler = brugerHandler;
    this.rekH = reklamationsHandler;
    startUp();
}

Putting the panel in the frame in the GUI:

public static void opret(ReklamationHandler reklamationHandler) {
    rHandler = reklamationHandler;
    SwingUtilities.invokeLater(opret);
}

static Runnable opret = new Runnable() {
    @Override
    public void run() {
        JFrame f = jframe;
        f.getContentPane().removeAll();
        JPanel opret = new OpretOpdater(bHandler, rHandler);
        f.getContentPane().add(opret);
        f.pack();
        f.setLocationRelativeTo(null);
    }
};

You should call requestFocusInWindow() only when components are visible/shown on a container or after pack() has been called and all components are added to the container or else it wont work.

Also please be sure to create Swing components on Event Dispatch Thread . If you haven't already have read on Concurrency in Swing .

The reason I mention the above is not creating and manipulating Swing components on the EDT can cause random artifacts in the code. ie focus is not being given etc.

This code below was created to show how calling requestFocusInWindow before a component is visible will not work but calling it after its visible works as expected.

Also note that removing the SwingUtilities block will cause the requestFocusInWindow not to work as expected (ie we might be given focus or not depending on our luck :P):

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Test {

    public Test() {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JTextField f1 = new JTextField(10);

        JTextField f2 = new JTextField(10);

        //f2.requestFocusInWindow(); //wont work (if uncomment this remember to comment the one after setVisible or you wont see the reults)

        JButton b = new JButton("Button");

        JPanel p = new JPanel();

        p.add(f1);//by default first added component will have focus
        p.add(f2);
        p.add(b);

        frame.add(p);

        //f2.requestFocusInWindow();//wont work
        frame.pack();//Realize the components.
        //f2.requestFocusInWindow();//will work
        frame.setVisible(true);

        f2.requestFocusInWindow();//will work
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {//if we remove this block it wont work also (no matter when we call requestFocusInWindow)
            @Override
            public void run() {
                new Test();
            }
        });
    }
}

I would suggest a read on How to Use the Focus Subsystem .

Often it is nice to indicate which field you want to have focus when you create the field and not separate the code by adding the request focus when the frame becomes visible.

Take a look at Dialog Focus which has a solution that is also applicable in this case. Using this approach your code would look like:

JTextField f2 = new JTextField(10);
f2.addAncestorListener( new RequestFocusListener() );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM