【问题标题】:Eclipse JFace's WizardsEclipse JFace 的向导
【发布时间】:2009-06-05 06:01:23
【问题描述】:

我需要一个向导,它的第二页内容取决于第一页的选择。第一个页面询问用户他想要创建的过滤器的“种类”,第二个页面要求用户创建一个所选“种类”的过滤器实例。

JFace 的向导页面内容(createControl(...) 方法)都是在向导打开时创建的,而不是在显示给定页面时创建的(这让 JFace 知道我猜的向导大小??)。

因此,我必须在打开向导之前创建第二页内容,但我不能,因为第二页的内容取决于第一页的选择。

目前我发现的更简洁的解决方案是在向导打开之前创建所有(秒)页面(及其内容)并覆盖第一页实现中的 getNextPage() 方法。

该解决方案的主要缺点是,当要创建许多第二页时,成本可能会很高。

您如何看待该解决方案?您如何管理向导的页面?有没有我错过的更清洁的解决方案?

【问题讨论】:

    标签: java eclipse jface


    【解决方案1】:

    如果您是其他几个页面,则该方法是正确的

    • 彼此完全不同
    • 取决于在上一页中所做的选择

    那你可以add the next page dynamically(也可以叫described here

    但如果您只有一个包含动态内容的下一页,您应该可以在onEnterPage() method 中创建该内容

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

    如eclipse一角文章Creating JFace Wizards

    我们可以通过覆盖任何向导页面的 getNextPage 方法来更改向导页面的顺序。在离开页面之前,我们将用户选择的值保存在模型中。在我们的示例中,根据旅行的选择,用户接下来将看到包含航班的页面或驾车旅行的页面。

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

    我们定义了一个方法来为PlanePageonEnterPage() 执行此初始化,并在移动到PlanePage 时调用此方法,即在第一页的getNextPage() 方法中强>。

    【讨论】:

      【解决方案2】:

      如果您想根据您在第一页上的选择启动一个新向导,您可以使用 JFace 基类org.eclipse.jface.wizard.WizardSelectionPage

      下面的示例显示了由扩展点定义的可用向导列表。 当您按 下一步 时,将启动选定的向导。

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

      对应的向导类如下所示:

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

      【讨论】:

      • 我重新格式化了你的代码,如果你不喜欢它 - 请回滚。
      【解决方案3】:

      另一种选择是@Override setVisible。届时您可以更新页面值或添加其他小部件。

      【讨论】:

        【解决方案4】:

        我有不同的解决方案。

        如果页面依赖于页面 1 的结果,则创建一个变量并将其传递给第一页,当该向导页面具有来自用户的选项时,页面关闭之前的最后一件事是将变量设置为所需的值。

        然后将此变量传递给向导,然后将其传递给下一个向导页面。然后做一个简单的 if 语句,这样你就可以同时选择两个选项。

        请记住,在大多数代码中,用户选项只有很小的差异,因此请记住不要陷入重复代码的困境。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-01
          • 2011-03-22
          • 2011-03-12
          • 1970-01-01
          • 2012-04-12
          • 2013-10-25
          相关资源
          最近更新 更多