简体   繁体   English

Eclipse JFace的向导

[英]Eclipse JFace's Wizards

I need a wizard which second page content depends on the first page's selection. 我需要一个向导,第二页内容取决于第一页的选择。 The first page asks the user the "kind" of filter he wants to create and the second one asks the user to create one filter instance of the selected "kind". 第一页询问用户他想要创建的过滤器的“种类”,第二页要求用户创建所选“种类”的一个过滤器实例。

JFace's wizards pages contents (createControl(...) method) are all created when the wizard is open and not when a given page is displayed (this allow JFace to know the wizard size I guess ??). JFace的向导页面内容(createControl(...)方法)都是在向导打开时创建的,而不是在显示给定页面时创建的(这允许JFace知道向导大小,我猜??)。

Because of this, I have to create my second page content BEFORE the wizard is opened BUT I can't since the second page's content depends on the first page selection. 因此,我必须在向导打开之前创建我的第二页内容但是我不能,因为第二页的内容取决于第一页的选择。

For now the cleaner solution I found consists in creating all (seconds) pages before the wizard is open (with their content) and override the getNextPage() method in the first page's implementation. 现在我找到的更清洁的解决方案包括在向导打开之前创建所有(秒)页面(带有它们的内容)并覆盖第一页实现中的getNextPage()方法。

The main drawback of that solution is that it can be be expensive when there are many second pages to create. 该解决方案的主要缺点是,当要创建许多第二页时,它可能很昂贵。

What do you think about that solution ? 您对该解决方案有何看法? How do you manage your wizard's pages ? 你如何管理向导的页面? Is there any cleaner solution I missed ? 有没有我错过的清洁解决方案?

The approach is right if you are several other pages which are 如果你是其他几个页面,那么这种方法是正确的

  • completely different one with another 与另一个完全不同
  • depends on the previous choices made in a previous page 取决于之前页面中的先前选择

Then you can add the next page dynamically (also as described here ) 然后你可以动态添加下一页 (也如这里所述

But if you have just a next page with a dynamic content, you should be able to create that content in the onEnterPage() method 但是如果您只有一个包含动态内容的下一页,您应该能够在onEnterPage()方法中创建该内容

public void createControl(Composite parent)
{
    //
    // create the composite to hold the widgets
    //
    this.composite = new Composite(parent, SWT.NONE);

    //
    // create the desired layout for this wizard page
    //
    GridLayout layout = new GridLayout();
    layout.numColumns = 4;
    this.composite.setLayout(layout);

    // set the composite as the control for this page
    setControl(this.composite);
}

void onEnterPage()
{
    final MacroModel model = ((MacroWizard) getWizard()).model;
    String selectedKey = model.selectedKey;
    String[] attrs = (String[]) model.macroMap.get(selectedKey);

    for (int i = 0; i < attrs.length; i++)
    {
        String attr = attrs[i];
        Label label = new Label(this.composite, SWT.NONE);
        label.setText(attr + ":");

        new Text(this.composite, SWT.NONE);
    }
    pack();
}

As shown in the eclipse corner article Creating JFace Wizards : 如eclipse角文章创建JFace向导所示

We can change the order of the wizard pages by overwriting the getNextPage method of any wizard page.Before leaving the page, we save in the model the values chosen by the user. 我们可以通过覆盖任何向导页面的getNextPage方法来更改向导页面的顺序。在离开页面之前,我们在模型中保存用户选择的值。 In our example, depending on the choice of travel the user will next see either the page with flights or the page for travelling by car. 在我们的示例中,根据旅行的选择,用户接下来会看到带有航班的页面或开车旅行的页面。

public IWizardPage getNextPage(){
   saveDataToModel();       
   if (planeButton.getSelection()) {
       PlanePage page = ((HolidayWizard)getWizard()).planePage;
     page.onEnterPage();
       return page;
   }
   // Returns the next page depending on the selected button
   if (carButton.getSelection()) { 
    return ((HolidayWizard)getWizard()).carPage;
   }
   return null;
}

We define a method to do this initialization for the PlanePage , onEnterPage() and we invoke this method when moving to the PlanePage , that is in the getNextPage() method for the first page . 我们定义了一个为PlanePageonEnterPage()初始化的方法,我们在移动到PlanePage时调用此方法,即第一页的getNextPage()方法

If you want to start a new wizard based on your selection on the first page, you can use the JFace base class org.eclipse.jface.wizard.WizardSelectionPage . 如果要根据第一页上的选择启动新向导,可以使用JFace基类org.eclipse.jface.wizard.WizardSelectionPage

The example below shows a list of available wizards defined by an extension point. 下面的示例显示了扩展点定义的可用向导列表。 When you press Next , the selected wizard is started. 按“ 下一步”时 ,将启动所选向导。

public class ModelSetupWizardSelectionPage extends WizardSelectionPage {

private ComboViewer providerViewer;
private IConfigurationElement selectedProvider;

public ModelSetupWizardSelectionPage(String pageName) {
    super(pageName);
}

private class WizardNode implements IWizardNode {
    private IWizard wizard = null;
    private IConfigurationElement configurationElement;

    public WizardNode(IConfigurationElement c) {
        this.configurationElement = c;
    }

    @Override
    public void dispose() {

    }

    @Override
    public Point getExtent() {
        return new Point(-1, -1);
    }

    @Override
    public IWizard getWizard() {
        if (wizard == null) {
            try {
                wizard = (IWizard) configurationElement
                        .createExecutableExtension("wizardClass");
            } catch (CoreException e) {

            }
        }
        return wizard;
    }

    @Override
    public boolean isContentCreated() {
        // TODO Auto-generated method stub
        return wizard != null;
    }

}

@Override
public void createControl(Composite parent) {
    setTitle("Select model provider");
    Composite main = new Composite(parent, SWT.NONE);
    GridLayout gd = new GridLayout(2, false);
    main.setLayout(gd);
    new Label(main, SWT.NONE).setText("Model provider");
    Combo providerList = new Combo(main, SWT.NONE);
    providerViewer = new ComboViewer(providerList);
    providerViewer.setLabelProvider(new LabelProvider() {
        @Override
        public String getText(Object element) {
            if (element instanceof IConfigurationElement) {
                IConfigurationElement c = (IConfigurationElement) element;
                String result = c.getAttribute("name");
                if (result == null || result.length() == 0) {
                    result = c.getAttribute("class");
                }
                return result;
            }
            return super.getText(element);
        }

    });
    providerViewer
            .addSelectionChangedListener(new ISelectionChangedListener() {
                @Override
                public void selectionChanged(SelectionChangedEvent event) {
                    ISelection selection = event.getSelection();
                    if (!selection.isEmpty()
                            && selection instanceof IStructuredSelection) {
                        Object o = ((IStructuredSelection) selection)
                                .getFirstElement();
                        if (o instanceof IConfigurationElement) {
                            selectedProvider = (IConfigurationElement) o;
                            setMessage(selectedProvider.getAttribute("description"));
                            setSelectedNode(new WizardNode(selectedProvider));
                        }
                    }

                }
            });
    providerViewer.setContentProvider(new ArrayContentProvider());
    List<IConfigurationElement> providers = new ArrayList<IConfigurationElement>();
    IExtensionRegistry registry = Platform.getExtensionRegistry();
    IExtensionPoint extensionPoint = registry
            .getExtensionPoint(<your extension point namespace>,<extension point name>);
    if (extensionPoint != null) {
        IExtension extensions[] = extensionPoint.getExtensions();
        for (IExtension extension : extensions) {
            IConfigurationElement configurationElements[] = extension
                    .getConfigurationElements();
            for (IConfigurationElement c : configurationElements) {
                providers.add(c);
            }
        }
    }
    providerViewer.setInput(providers);
    setControl(main);

}

The corresponding wizard class looks like this: 相应的向导类如下所示:

 public class ModelSetupWizard extends Wizard {

private ModelSetupWizardSelectionPage wizardSelectionPage;

public ModelSetupWizard() {
    setForcePreviousAndNextButtons(true);
}

@Override
public boolean performFinish() {
            // Do what you have to do to finish the wizard
    return true;
}

@Override
public void addPages() {
    wizardSelectionPage = new ModelSetupWizardSelectionPage("Select a wizard");
    addPage(wizardSelectionPage);

}
}

Another alternative is to @Override setVisible . 另一种选择是@Override setVisible You can update page values or add additional widgets at that time. 您可以在此时更新页面值或添加其他小部件。

I have a different solution. 我有一个不同的解决方案。

If page depends on the result of page 1, create a variable and pass it into to first page, when that wizard page has the option from the user, then the last thing before the page is closed is to set the variable to the required value. 如果页面取决于第1页的结果,则创建一个变量并将其传递到第一页,当该向导页面具有来自用户的选项时,页面关闭之前的最后一项是将变量设置为所需的值。

Then pass this variable to wizard, then pass it to the next wizard page. 然后将此变量传递给向导,然后将其传递给下一个向导页面。 Then do a simple if statement and that way you get both choices together. 然后做一个简单的if语句,这样你就可以得到两个选择。

Remember that in most code there is only a small difference in the user options, so remember not to get bogged down in duplicating your code. 请记住,在大多数代码中,用户选项只有很小的差异,所以切记不要陷入重复代码的困境。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM