【问题标题】:How to use FutureTask<V>, waiting for ui event?如何使用 FutureTask<V>,等待 ui 事件?
【发布时间】:2016-03-22 21:10:32
【问题描述】:

我有一个接口方法,它应该返回一个 Future 对象。

Future<Result> doSomething()

这个方法的实现显示了一些ui(javafx)。 其中一个 ui 元素有一个侦听器,需要调用它才能接收实际结果,我需要。

我如何实现这一目标? 有没有更好的解决方案?

这是我需要等待的示例操作:

// this is some framework method I cannot change
@Override
public Data execute(Data data) {
    Future<Data> dataFuture = handler.doSomething(data);
    // this should basically wait until the user clicked a button
    return dataFuture.get();
}

// handler implementation
public Future<Data> doSomething(Data data) {
    // the question is how to implement this part, to be able to
    // return a future object
    Button button = new Button("Wait until click");
    // create thread that waits for the button click ?!????
    // modify incoming data object when the button was clicked
    // somehow create the Future object that's bound to the button click
    return future;
}

这就是我想要实现的目标:

  1. 我的方法 doSomething 显示了一个带有按钮的新场景 (ui)
  2. 并立即返回未来对象
  3. future.get() 等待用户按下按钮

限制:必须在没有额外库的情况下使用 >=Java7

【问题讨论】:

  • 从哪里调用这个方法? (FX 应用程序线程还是后台线程?)为什么需要以这种方式做事(即为什么不使用通常的事件驱动机制来“在按下按钮时执行某事”)?按钮将显示在哪里?在对话框中?在现有阶段?您可能需要提供 许多 更多详细信息,或者最好提供一个完整的可执行示例,以阐明您正在尝试做什么。

标签: java javafx futuretask


【解决方案1】:

使用javafx.concurrent.Task。它源自FutureTask。链接的 javadoc 中有大量关于任务用法的示例。

Oracle 还提供了一个讨论任务用法的教程:

我认为这就是您想要的,但我可能已经理解了这个问题,如果是这样,请稍微编辑问题以澄清要求(可能使用mcve)。让我有点不确定的是您的标题“等待 ui 事件?”中的部分,我不太确定在这种情况下这意味着什么。

【讨论】:

  • 我希望这个例子现在更好。
  • 不幸的是,我仍然有点不清楚,您的示例仍然缺少很多内容。诸如 FutureTask 之类的并发构造仅在您实际发生并发工作(应用程序是多线程的)时才有意义,但您的示例不会创建任何线程。所以我想知道你是否真的需要一个 FutureTask 或者你是否只是想获得一个异步回调(你已经在你的按钮的动作事件处理程序中拥有它)。如果你提供一个完整的程序,别人可以复制粘贴运行,它可能更容易理解。
【解决方案2】:

这是我一直在寻找的解决方案。这不是很好,因为 Thread.sleep 不能说服我。

但现在你大概知道我想要达到的目标了

// make sure this is not called on the ui thread
public Future<Data> doSomething(Data data) {
    WaitingFuture future = new WaitingFuture(data);
    Platform.runLater(() -> {
                Button button = new Button("Wait until click");
                button.setOnAction(future);
                // show button on ui...
            });
    favouriteExecutorService.submit(future);
    return future;
}

static class WaitingFuture extends Task<Data> implements EventHandler<ActionEvent> {
    private Data data;

    WaitingFuture(Data originalData) {
        this.data = originalData;
    }

    private Data waitingData;

    @Override
    public void handle(ActionEvent event) {
        waitingData = data.modify();
    }

    @Override
    protected Data call() throws Exception {
        while (waitingData == null) {
            Thread.sleep(100);
        }
        return waitingData;
    }
}

【讨论】:

    猜你喜欢
    • 2011-08-27
    • 1970-01-01
    • 2013-03-02
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 2021-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多