Eclipse JFace Wizards

Мне нужен мастер, содержимое второго страницы которого зависит от выбора первой страницы. Первая страница запрашивает у пользователя "вид" фильтра, который он хочет создать, а второй просит пользователя создать один экземпляр фильтра выбранного "вида".

Содержимое веб-страниц JFace wizard (метод createControl (...)) создается при открытии мастера, а не при отображении данной страницы (это позволяет JFace узнать размер мастера, который я предполагаю?).

Из-за этого я должен создать свой второй контент страницы ДО того, как мастер открыт, но я не могу, поскольку содержимое второй страницы зависит от выбора первой страницы.

В настоящее время решение, которое я нашел, состоит в создании всех (секунд) страниц до того, как мастер откроется (с их содержимым) и переопределит метод getNextPage() в реализации первой страницы.

Основным недостатком этого решения является то, что он может быть дорогостоящим, когда есть много вторых страниц для создания.

Что вы думаете об этом решении? Как вы управляете страницами мастера? Есть ли какое-нибудь более чистое решение, которое я пропустил?

Ответы

Ответ 1

Подход правильный, если вы несколько других страниц, которые

  • совершенно другой с другим
  • зависит от предыдущих вариантов, сделанных на предыдущей странице.

Затем вы можете добавить следующую страницу динамически (также как описанный здесь)

Но если у вас есть только следующая страница с динамическим контентом, вы сможете создать этот контент в 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();
}

Как показано в статье угла затмения Создание 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;
}

Мы определим метод для этой инициализации для PlanePage, onEnterPage(), и мы вызываем этот метод при переходе на 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, и вы получите оба варианта вместе.

Помните, что в большинстве кодов есть небольшая разница в пользовательских параметрах, поэтому не забудьте увязнуть в дублировании кода.