javaeclipsejface

Eclipse JFace's Wizards (Again ...)


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();
                    }
                }
            );
        }
    }
    

    Note that with Eclipse 4.29 (Q3 2023)

    Control.setFocus() no longer activates its Shell

    Previously calling Control.setFocus() also activated its Shell. This behavior was never documented and was never explained why it existed. But it caused problems: setting focus to a control in a background Shell caused the Shell to jump on user.

    Now setting focus just sets focus, even if the Shell is in the background. To also bring Shell to front, explicitly call Shell.setActive().

    This change can be disabled using a Java property.
    For Example, add this VM argument in eclipse.ini or on the command line after -vmargs:

      -Dorg.eclipse.swt.internal.activateShellOnForceFocus=true
    

    Note: this property is only added temporarily and will be removed later.

    See SWT Issue 450