Reputation: 15623
I have a subclass of JDialog... the overridden setVisible method looks like this:
public void setVisible( boolean visible ){
super.setVisible( visible );
if( visible ){
inputJTF.requestFocus();
}
}
In fact when I display the JDialog the focus is on the JTF... but the latter happens also to be the "first" component (NORTH panel) in the JDialog, so that's not surprising.
But my testing code is telling me other things:
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 );
}
});
... so in fact I get told that the "focus owner" is null... and the JTF doesn't have focus. Can anyone explain what's going on?
Upvotes: 0
Views: 128
Reputation: 15623
Aha... this turns out to be one of those "Gotcha" things with JUnit and Java GUI.
The test in my code fails ... but the following code doesn't:
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() );
}
});
... if the robot.delay()
is reduced to 1, or absent, the failure happens.
Clearly this is to do with the finite time needed to realise the JDialog
.
Rob Camick's answer is interesting, and RequestFocusListener
works as intended.
However his answer doesn't actually answer the question: which was: what's going on and why does this test fail?
Upvotes: 0
Reputation: 324098
Most dialogs are modal, which means the statement after the setVisible(true) statement is not executed until the dialog is closed.
By default focus will go to the first component on the dialog.
If for some reason you need focus on a different component then check out Dialog Focus for a solution that allow you to control which component get focus.
This solution uses an AncestorListener
to place focus on a component once the component is displayed on a visible dialog/frame.
Upvotes: 3