我有一个框架,我在其中加载一个面板。它工作得很好,但加载时没有焦点。按下选项卡没有帮助。我必须用鼠标按下一个文本字段。我试过: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() );