如何在 javafx 中操作 Future 的结果
How to manipulate the result of a Future in javafx
这是我的 JavaFX 控制器
public class MainController {
private Future<Graph> operation;
private ExecutorService executor = Executors.newSingleThreadExecutor();
@FXML
private void createSession() { //invoked by a button click in the view
//GraphCreationSession implements Callable<Graph>
GraphCreationSession graphSession = new GraphCreationSession();
if (operation != null && !operation.isDone()) {
//cancel previous session
operation.cancel(true);
}
operation = executor.submit(graphSession);
???
}
}
所以我的问题是,在 javaFX 上下文中处理 Future
结果的成语是什么?
我知道我可以 operation.get()
线程将阻塞直到操作完成,但我会阻塞应用程序线程。我正在考虑 Callable
完成时的回调,我发现 CompletableFuture
,哪种方式通过 thenAccept but based on this answer 线程仍将被阻塞,这失败了未来的重点,就像答案提到的那样。
在我的特定情况下,Callable(示例中的图表)的结果包含一个我希望在操作完成时显示在面板中的结果。
最简单的方法是更改 GraphCreationSession
,使其成为 Task<Graph>
的子类,而不是 Callable<Graph>
的实现:
public class GraphCreationSession extends Task<Graph> {
@Override
public Graph call() throws Exception {
// implementation as before...
}
}
那你可以做
public class MainController {
private ExecutorService executor = Executors.newSingleThreadExecutor();
private GraphCreationSession graphSession ;
@FXML
private void createSession() { //invoked by a button click in the view
if (graphSession != null && !graphSession.getState()==Worker.State.RUNNING) {
//cancel previous session
graphSession.cancel(true);
}
graphSession = new GraphCreationSession();
graphSession.setOnSucceeded(event -> {
Graph graph = graphSession.getValue();
// update UI...
});
executor.execute(graphSession);
}
}
如果您不能更改 GraphCreationSession
,或者希望它独立于 javafx API,那么只需将其包装在一个简单的 Task
实现中:
public class MainController {
private Task<Graph> graphSession ;
// ...
@FXML
public void createSession() {
// ...
graphSession = new Task<Graph>() {
@Override
public Graph call() throws Exception {
return new GraphCreationSession().call();
}
};
graphSession.setOnSucceeded(...);
executor.execute(graphSession);
}
}
这是我的 JavaFX 控制器
public class MainController {
private Future<Graph> operation;
private ExecutorService executor = Executors.newSingleThreadExecutor();
@FXML
private void createSession() { //invoked by a button click in the view
//GraphCreationSession implements Callable<Graph>
GraphCreationSession graphSession = new GraphCreationSession();
if (operation != null && !operation.isDone()) {
//cancel previous session
operation.cancel(true);
}
operation = executor.submit(graphSession);
???
}
}
所以我的问题是,在 javaFX 上下文中处理 Future
结果的成语是什么?
我知道我可以 operation.get()
线程将阻塞直到操作完成,但我会阻塞应用程序线程。我正在考虑 Callable
完成时的回调,我发现 CompletableFuture
,哪种方式通过 thenAccept but based on this answer 线程仍将被阻塞,这失败了未来的重点,就像答案提到的那样。
在我的特定情况下,Callable(示例中的图表)的结果包含一个我希望在操作完成时显示在面板中的结果。
最简单的方法是更改 GraphCreationSession
,使其成为 Task<Graph>
的子类,而不是 Callable<Graph>
的实现:
public class GraphCreationSession extends Task<Graph> {
@Override
public Graph call() throws Exception {
// implementation as before...
}
}
那你可以做
public class MainController {
private ExecutorService executor = Executors.newSingleThreadExecutor();
private GraphCreationSession graphSession ;
@FXML
private void createSession() { //invoked by a button click in the view
if (graphSession != null && !graphSession.getState()==Worker.State.RUNNING) {
//cancel previous session
graphSession.cancel(true);
}
graphSession = new GraphCreationSession();
graphSession.setOnSucceeded(event -> {
Graph graph = graphSession.getValue();
// update UI...
});
executor.execute(graphSession);
}
}
如果您不能更改 GraphCreationSession
,或者希望它独立于 javafx API,那么只需将其包装在一个简单的 Task
实现中:
public class MainController {
private Task<Graph> graphSession ;
// ...
@FXML
public void createSession() {
// ...
graphSession = new Task<Graph>() {
@Override
public Graph call() throws Exception {
return new GraphCreationSession().call();
}
};
graphSession.setOnSucceeded(...);
executor.execute(graphSession);
}
}