我需要一个向导,第二页内容取决于第一页的选择。第一页询问用户他想要创建的过滤器的“种类”,第二页要求用户创建一个所选“种类”的过滤器实例。
JFace的向导页面内容(createControl(...)方法)都是在向导打开时创建的,而不是在显示给定页面时创建的(这允许JFace知道向导大小,我猜??)。
因此,我必须在打开向导之前创建我的第二页内容但是我不能,因为第二页的内容取决于第一页的选择。
现在我找到的更清洁的解决方案包括在向导打开之前创建所有(秒)页面(带有它们的内容)并覆盖第一页实现中的getNextPage()方法。
该解决方案的主要缺点是,当要创建许多第二页时,它可能会很昂贵。
您如何看待该解决方案?你如何管理向导的页面?我错过了哪些清洁解决方案?
答案 0 :(得分:9)
如果您是其他几个
的页面,那么这种方法是正确的然后你可以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();
}
如日食角落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;
}
我们定义了为PlanePage
,onEnterPage()
执行此初始化的方法,我们在移动到PlanePage
时调用此方法,即getNextPage()
第一页的方法。
答案 1 :(得分:5)
如果要根据第一页上的选择启动新向导,可以使用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);
}
}
答案 2 :(得分:1)
另一种选择是@Override setVisible。您可以在此时更新页面值或添加其他小部件。
答案 3 :(得分:0)
我有一个不同的解决方案。
如果页面取决于第1页的结果,请创建一个变量并将其传递到第一页,当该向导页面具有来自用户的选项时,页面关闭之前的最后一件事是将变量设置为所需的价值。
然后将此变量传递给向导,然后将其传递给下一个向导页面。然后做一个简单的if语句,这样你就可以得到两个选择。
请记住,在大多数代码中,用户选项只有很小的差异,所以请记住在复制代码时不要陷入困境。