当 JDialog 可见时,将焦点放在 JDialog 中的 JTextField
Put focus on a JTextField in JDialog when latter made visible
我有一个 JDialog 的子类...重写的 setVisible 方法如下所示:
public void setVisible( boolean visible ){
super.setVisible( visible );
if( visible ){
inputJTF.requestFocus();
}
}
事实上,当我显示 JDialog 时,焦点 是 在 JTF 上...但后者恰好也是 "first" 组件(NORTH 面板) JDialog,所以这并不奇怪。
但我的测试代码告诉我其他事情:
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
app.mainFrame.searchDlg.setVisible( true );
// all 3 of these asserts fail...
assertTrue( app.mainFrame.searchDlg.inputJTF.hasFocus() );
Component focusOwner = app.mainFrame.searchDlg.getFocusOwner();
assertFalse( focusOwner == null );
assertTrue( String.format( "# focus owner %s", focusOwner.getClass()), focusOwner == app.mainFrame.searchDlg.inputJTF );
}
});
...所以实际上我被告知 "focus owner" 为空...并且 JTF 没有焦点。谁能解释一下这是怎么回事?
大多数对话框都是模态的,也就是说setVisible(true)语句之后的语句直到对话框关闭才会执行。
默认情况下,焦点将转到对话框中的第一个组件。
如果出于某种原因您需要专注于不同的组件,请查看 Dialog Focus 的解决方案,让您控制哪个组件获得焦点。
此解决方案使用 AncestorListener
在组件显示在可见 dialog/frame 上后将焦点放在组件上。
啊哈...结果证明这是 "Gotcha" JUnit 和 Java GUI 的事情之一。
我的代码中的测试失败了...但以下代码没有:
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
searchDlg.setVisible( true );
assertTrue( searchDlg.queryString == null );
}
});
Robot robot = new Robot();
robot.delay( 10 );
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
// now passes
assertTrue( app.mainFrame.searchDlg.inputJTF.hasFocus() );
}
});
...如果 robot.delay()
减为 1 或不存在,则失败发生。
显然这与实现 JDialog
.
所需的有限时间有关
Rob Camick 的回答很有趣,RequestFocusListener
按预期工作。
然而,他的回答实际上并没有回答问题:这是:发生了什么,为什么这个测试失败了?
我有一个 JDialog 的子类...重写的 setVisible 方法如下所示:
public void setVisible( boolean visible ){
super.setVisible( visible );
if( visible ){
inputJTF.requestFocus();
}
}
事实上,当我显示 JDialog 时,焦点 是 在 JTF 上...但后者恰好也是 "first" 组件(NORTH 面板) JDialog,所以这并不奇怪。
但我的测试代码告诉我其他事情:
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
app.mainFrame.searchDlg.setVisible( true );
// all 3 of these asserts fail...
assertTrue( app.mainFrame.searchDlg.inputJTF.hasFocus() );
Component focusOwner = app.mainFrame.searchDlg.getFocusOwner();
assertFalse( focusOwner == null );
assertTrue( String.format( "# focus owner %s", focusOwner.getClass()), focusOwner == app.mainFrame.searchDlg.inputJTF );
}
});
...所以实际上我被告知 "focus owner" 为空...并且 JTF 没有焦点。谁能解释一下这是怎么回事?
大多数对话框都是模态的,也就是说setVisible(true)语句之后的语句直到对话框关闭才会执行。
默认情况下,焦点将转到对话框中的第一个组件。
如果出于某种原因您需要专注于不同的组件,请查看 Dialog Focus 的解决方案,让您控制哪个组件获得焦点。
此解决方案使用 AncestorListener
在组件显示在可见 dialog/frame 上后将焦点放在组件上。
啊哈...结果证明这是 "Gotcha" JUnit 和 Java GUI 的事情之一。
我的代码中的测试失败了...但以下代码没有:
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
searchDlg.setVisible( true );
assertTrue( searchDlg.queryString == null );
}
});
Robot robot = new Robot();
robot.delay( 10 );
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
// now passes
assertTrue( app.mainFrame.searchDlg.inputJTF.hasFocus() );
}
});
...如果 robot.delay()
减为 1 或不存在,则失败发生。
显然这与实现 JDialog
.
Rob Camick 的回答很有趣,RequestFocusListener
按预期工作。
然而,他的回答实际上并没有回答问题:这是:发生了什么,为什么这个测试失败了?