Java 向导中的计算

Java 向导中的计算,java,eclipse-plugin,Java,Eclipse Plugin,这是一个更一般的问题。我们有很多向导,其中一些启动一个长时间运行的过程,并在运行后显示结果。问题是:做长时间计算的正确方法是什么 以前,大多数向导在DialogPagesetVisible中进行计算,类似于: public void setVisible(final boolean visible) { if (visible) { getWizard().getContainer().run(true, true, new MyCalculation()); }

这是一个更一般的问题。我们有很多向导,其中一些启动一个长时间运行的过程,并在运行后显示结果。问题是:做长时间计算的正确方法是什么

以前,大多数向导在DialogPagesetVisible中进行计算,类似于:

public void setVisible(final boolean visible) {
    if (visible) {
        getWizard().getContainer().run(true, true, new MyCalculation());
    }
    super.setVisible(visible);
}
我认为这不是一个好主意,因为在这些方法中通常会调用很多getWizard。此外,通常父向导将强制转换为特定的实现,以从其他页面获取输入值或将结果设置为其他页面。所以通常看起来像这样:

public void setVisible(final boolean visible) {
    if (visible) {
        Input input = ((MyCalculationWizard)getWizard()).getInputPage().getInput();
        MyCalculation calculation = new MyCalculation(input);
        getWizard().getContainer().run(true, true, calculation);
        Output output = calculation.getOutput();
        ((MyCalculationWizard)getWizard()).getOtherPage().setOutput(output);
    }
    super.setVisible(visible);
}
从代码上看,你知道这是一种非常糟糕的风格

因此,我们用WizardgetNextPage中计算的内容替换了它:

这样,向导可以比页面更好地进行微调,而且向导已经知道它的页面,并且可以比页面更好地处理输入和输出

缺点是:getNextPage经常被调用来更新按钮,而且每次向导都喜欢这样做。因此,虽然它适用于小流程,但对于长时间运行的流程,它并没有削减

在进行了更多的探索之后,我发现在覆盖WizardsetContainer时,以下方法可以发挥作用:

这里最大的优点是,只有当向导想要在页面之间跳转时,才会调用侦听器,并且我们能够真正微调计算,例如,在调用“Previous”时不调用侦听器。我们甚至无法在所有event.doit=false之后显示下一页

缺点是将容器强制转换为向导对话框,因为它可能是一个完全不同的实现


因此,问题是:在向导中启动长流程的最佳方式是什么?

澄清一下:您想要的是能够在页面发生更改时判断?您想要运行长时间计算的事实与问题无关,因为您已经知道如何运行长时间计算calculation@immibis对我不认为这是完全无关的,因为有些地方会收到页面更改的通知,这些更改无法基于向导内部进行计算。向导页面有一个getContainer,因此您不需要执行getWizard.getContainer。我不明白你认为setVisible方法的问题是什么。@greg-449我添加了一个更大的例子来解释为什么使用setVisible是错误的。getContainer并没有减少这一事实。
public IWizardPage getNextPage(final IWizardPage page) {
    final IWizardPage nextPage = super.getNextPage(page);
    if (nextPage == this.myResultPage)
        getContainer().run(true, true, new MyCalculation());
    return nextPage;
}
public void setContainer(final IWizardContainer wizardContainer) {
    final IWizardContainer oldContainer = getContainer();
    if (oldContainer instanceof WizardDialog) 
        ((WizardDialog) oldContainer).removePageChangingListener(this);
    super.setContainer(wizardContainer);
    if (wizardContainer instanceof WizardDialog)
        ((WizardDialog) wizardContainer).addPageChangingListener(this);
}

public void handlePageChanging(final PageChangingEvent event) {
    final IWizardPage currentPage = (IWizardPage) event.getCurrentPage();
    final IWizardPage nextPage = (IWizardPage) event.getTargetPage();

    if (currentPage == this.myInputPage && nextPage == this.myResultPage)
        getContainer().run(true, true, new MyCalculation());
}