在加载面板时关注组件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在加载面板时关注组件相关的知识,希望对你有一定的参考价值。

我有一个框架,我加载一个面板。它工作正常,但加载时没有任何焦点。按下选项卡没有帮助。我必须使用鼠标按文本字段。我试过: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);
    }
};
答案

只有当组件可见/显示在容器上或调用requestFocusInWindow()并且所有组件都添加到容器中或者它不起作用时,才应调用pack()

另外请务必在Event Dispatch Thread上创建Swing组件。如果你还没有读过Concurrency in 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();
            }
        });
    }
}

我建议读一下How to Use the Focus Subsystem

另一答案

通常,在创建字段时指示要聚焦的字段并且在框架变为可见时通过添加请求焦点而不分隔代码是很好的。

看看Dialog Focus,它有一个适用于这种情况的解决方案。使用此方法,您的代码将如下所示:

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

以上是关于在加载面板时关注组件的主要内容,如果未能解决你的问题,请参考以下文章

在 Blazor (.razor) 组件中添加多个组件

重新加载时刷新片段

在片段中添加上滑面板

损坏的顶点和片段着色器

单击链接加载组件

如何在页面加载之前隐藏可切换的 p:panel?