加载面板时,将焦点放在零部件上



我有一个框架,我在其中加载一个面板。它工作得很好,但加载时没有焦点。按下选项卡没有帮助。我必须用鼠标按下一个文本字段。我试过:jtextfield1.requestFocus();jtextfiel1.requestFocusInWindow();,但都不起作用。

我做错了什么?

JPanel:中的构造函数

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

将面板放入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);
    }
};

只有当组件在容器上可见/显示时,或者在调用pack()并将所有组件添加到容器后,才应调用requestFocusInWindow(),否则将无法工作。

此外,请确保在事件调度线程上创建Swing组件。如果您还没有阅读过Swing中的并发性。

我提到上面的原因是没有在EDT上创建和操作Swing组件可能会导致代码中出现随机伪影。即没有给出焦点等。

创建下面的代码是为了显示在组件可见之前调用requestFocusInWindow是如何不起作用的,但在组件可见之后调用它是如何按预期起作用的。

还要注意,移除SwingUtilities块将导致requestFocusInWindow无法按预期工作(即,我们可能会得到关注或不关注,这取决于我们的运气: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();
            }
        });
    }
}

我建议阅读一下《如何使用焦点子系统》。

通常,在创建字段时,最好指明要关注的字段,而不是在框架可见时通过添加请求焦点来分离代码。

看看Dialog Focus,它有一个同样适用于这种情况的解决方案。使用这种方法,您的代码将看起来像:

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

最新更新