Eclipse JFace's Wizards (Again …)
Question
Now that I am able to set the content of my second wizard's page depending on the first page selection, I am looking for a way to give the focus to my 2nd page's content when the user clicks the next button on the first page.
By default, when the user click the next button, the focus is given to the button composite (next, back or finish button depending on the wizard configuration)
The only way I found to give focus to my page's content is the following one:
public class FilterWizardDialog extends WizardDialog {
public FilterWizardDialog(Shell parentShell, IWizard newWizard) {
super(parentShell, newWizard);
}
@Override
protected void nextPressed() {
super.nextPressed();
getContents().setFocus();
}
}
To me it's a little bit "boring and heavy" to have to override the WizardDialog class in order to implement this behavior. More over, the WizardDialog javadoc says:
Clients may subclass
WizardDialog
, although this is rarely required.
What do you think about this solution ? Is there any easier and cleaner solution to do that job ?
Solution
This thread suggests:
In your wizard page, use the inherited
setVisible()
method that is called automatically before your page is shown :
public void setVisible(boolean visible) {
super.setVisible(visible);
// Set the initial field focus
if (visible) {
field.postSetFocusOnDialogField(getShell().getDisplay());
}
}
The postSetFocusOnDialogField method contains :
/**
* Posts <code>setFocus</code> to the display event queue.
*/
public void postSetFocusOnDialogField(Display display) {
if (display != null) {
display.asyncExec(
new Runnable() {
public void run() {
setFocus();
}
}
);
}
}
OTHER TIPS
VonC's answer works great, I personally found it to be a little easier to work with like this though:
@Override
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible) {
Control control = getControl();
if (!control.setFocus()) {
postSetFocus(control);
}
}
}
private void postSetFocus(final Control control) {
Display display = control.getDisplay();
if (display != null) {
display.asyncExec(new Runnable() {
@Override
public void run() {
control.setFocus();
}
});
}
}