gpt4 book ai didi

JavaFX - 从 gui 接收事件后返回主线程

转载 作者:行者123 更新时间:2023-11-29 08:26:29 24 4
gpt4 key购买 nike

我正在编写 JavaFX 应用程序并意识到 FX 线程上发生了太多事情。根本原因之一是 gui 事件,如按钮单击,在 FX 线程上产生后端操作。实际上,在收到事件后,我们就在 FX 线程上,所以任何进一步的调用都在它上面。有什么方法可以简单地返回到 MAIN 应用程序线程,然后在需要时返回 Platform.runLater,或者我必须使用例如 RX 或某些执行程序服务来处理它?<​​/p>

谢谢

最佳答案

退出事件循环的方式非常简单——就是 Java。使用您通常会使用的任何东西——执行程序、队列等。

例如,要“在后台”完成一些事情然后更新 GUI,您可以做类似的事情

final Executor backgroundWorker = Executors.newSingleThreadExecutor();
...
backgroundWorker.execute(()-> // from the EventLoop into the Worker
{
val result = doThatLongRunningTask();
Platform.runLater(() -> // back from the Worker to the Event Loop
{
updateUiWithResultOfLongRunningTask(result);
}
});

我通常希望将 main 线程提供给事件循环,并使用自定义执行程序进行后台工作(因为后台工作是特定于应用程序的,所以可能需要更多线程,等等。 ).


如果出于任何异国情调的原因(我真的想不出)你想要相反的方式:

因此,要将主线程用作执行器,我们只需要:

public final class MyApp extends Application {
private static final Logger LOG = LoggerFactory.getLogger(MyApp.class);
private static final Runnable POISON_PILL = () -> {};
private final BlockingQueue<Runnable> tasks = new LinkedBlockingQueue<>();
private final Executor backgroundWorker = this::execute;
private final Future<Void> shutdownFuture = new CompletableFuture<>();
private final Executor eventLoop = Executors.newSingleThreadExecutor();

/** Get background worker */
public Executor getBackgroundWorker() {
return backgroundWorker;
}

/** Request backgroun worker shutdown */
public Future shutdownBackgroundWorker() {
execute(POISON_PILL);
return shutdownFuture;
}

private void execute(Runnable task) {
tasks.put(task);
}

private void runWorkerLoop() throws Throwable {
Runnable task;
while ((task = tasks.take()) != POISON_PILL) {
task.run();
}
shutdownFuture.complete(null);
}

public static void main (String... args) throws Throwable {
final MyApp myApp = new MyApp(args);

LOG.info("starting JavaFX (background) ...");
eventLoop.execute(myApp::launch);

LOG.info("scheduling a ping task into the background worker...");
myApp.runLater(() -> {
LOG.info("#1 we begin in the event loop");
myApp.getBackgroundWorker().execute(() -> {
LOG.info("#2 then jump over to the background worker");
myApp.runLater(() -> {
LOG.info("#3 and then back to the event loop");
});
});
});

LOG.info("running the backgound worker (in the foreground)...");
myApp.runWorkerLoop();
}
}

关于JavaFX - 从 gui 接收事件后返回主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52439107/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com