当前位置: 首页 > 知识库问答 >
问题:

多线程JavaFX UI

华恩
2023-03-14

我有两个交织在一起的多线程问题。

我在使用spring boot的JavaFX桌面应用程序中有一个SplitPane。左边是树视图,右边是选项卡窗格。开始时,SplitPane设备位于右侧边缘,隐藏了TabPane。当用户在树中选择一个项目时,两件事将同时发生:

首先,根据选择,创建10个选项卡。选项卡因所选对象而异。每个选项卡都显示与选定对象相关的详细数据。大多数选项卡包含图表,但也包含文本。

其次,由于选项卡的设置需要几秒钟的时间(需要从DB中提取数据),所以想法是将TabPane Devicer缓慢地“滚动”到左侧,隐藏树。这会给用户留下应用程序仍在运行的印象,并使转换更加柔和。我不喜欢等待,等待,。。猛敲

一个问题是,我使用的时间线(见下文)不连贯,我无法使它无缝地并行设置选项卡。

选项卡的创建在一个专用的任务中运行,每个选项卡创建者使用Platform.run稍后()。第二个问题是,我不确定这是否是编码的最佳方式。我的意思是,几乎所有的选项卡都被顶部隐藏,但所有的选项卡都是在应用程序线程中一个接一个地创建的。

换句话说,伪代码看起来像这样:

KeyValue keyValue = new KeyValue(splitPane.getDividers().get(0).positionProperty(), 0.1);
Timeline timeline = new Timeline(new KeyFrame(Duration.millis(300), keyValue));
timeline.play();

Task task = new Task<Void>() {
    @Override public Void call() {
       Platform.runLater(()-> {
           createTabA();
       }

       ..

       Platform.runLater(()-> {
           createTabZ();
       }

       return null;
    }
};
Thread thread = new Thread(task);
thread.setDaemon(true);
thread.start();

我还更改了顺序,在开始线程后有了时间线。看起来不一样,但仍不像预期的那样。

我如何改进我的多线程逻辑并消除bucking?

顺便说一句:在实际代码中,我已经在这个过程运行时更改了光标,以使它更易于用户理解。

提前感谢您!

共有1个答案

罗允晨
2023-03-14

Runnables传递给Platform.run稍后在JavaFX应用程序线程上运行,并从后台线程快速连续多次调用Platform.run稍后具有JavaFX可以决定在Tab创建之间进行布局的唯一好处。选项卡创建不会变得更快。

将Runnable传递给平台。runLater不应包含任何长时间运行的操作。

而是在背景线程上创建选项卡,但不要从此线程将其附加到场景。(只要不修改附加到场景的内容,在后台线程上创建(部分)场景就不是问题)

如果您可以在任务结束时一次添加所有选项卡,请考虑使用任务

Task<List<Tab>> task = new Task<List<Tab>>() {
    @Override public List<Tab> call() {
       List<Tab> result = new ArrayList<>(1 + 'Z' - 'A');

       for (char c = 'A'; c <= 'Z'; c++) {
           result.add(createTab(c));
       }

       return result;
    }
};
task.setOnSucceeded(evt -> tabPane.getTabs().addAll(task.getValue()));
...

否则,在后台线程上创建选项卡,但将其添加到应用程序线程上的选项卡窗格中:

Task<Void> task = new Task<Void>() {
    @Override public Void call() {
       for (char c = 'A'; c <= 'Z'; c++) {
           final Tab tab = createTab(c);
           Platform.runLater(() -> tabPane.getTabs().add(tab));
       }

       return null;
    }
};

 类似资料:
  • typora-copy-images-to: img 1. 多线程概述 人们在日常生活中,很多事情都是可以同时进行的。例如,一个人可以一边听音乐,一边打扫房间,可以一边吃饭,一边看电视。在使用计算机时,很多任务也是可以同时进行的。例如,可以一边浏览网页,一边打印文档,还可以一边聊天,一边复制文件等。计算机这种能够同时完成多项任务的技术,就是多线程技术。Java是支持多线程的语言之一,它内置了对多线

  • 使用 [Web Workers][web-workers]可以在系统级线程中运行JavaScript。 多线程Node.js 在 webPreferences中将 n​​odeIntegrationInWorker选项设置为 true,可以在Electron的Web Workers中使用Node.js功能: 1 let win = new BrowserWindow({ 2 webPreferen

  • If you use Casbin in a multi-threading manner, you can use the synchronized wrapper of the Casbin enforcer: https://github.com/casbin/casbin/blob/master/enforcer_synced.go (GoLang) and https://github.

  • 多线程 Swift多线程编程方案 Thread Cocoa Operation (Operation 和 OperationQueue) Grand Central Dispath (GCD) 1. Thread在三种多线程技术中是最轻量级的, 但需要自己管理线程的生命周期和线程同步. 线程同步对数据的加锁会有一定的系统开销. detachNewThread(_ block: @escaping

  • 在多线程运行环境中, Configuration 实例, Template 实例和数据模型应该是永远不能改变(只读)的对象。 也就是说,创建和初始化它们(如使用 set... 方法)之后,就不能再修改它们了(比如不能再次调用 set... 方法)。 这就允许我们在多线程环境中避免代价很大的同步锁问题。要小心 Template 实例; 当使用了 Configuration.getTemplate 方

  • 多任务可以由多进程完成,也可以由一个进程内的多线程完成。 我们前面提到了进程是由若干线程组成的,一个进程至少有一个线程。 由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。 Python的标准库提供了两个模块:thread和threading,thread是低级模块,th

  • 多任务可以由多进程完成,也可以由一个进程内的多线程完成。 我们前面提到了进程是由若干线程组成的,一个进程至少有一个线程。 由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。 Python的标准库提供了两个模块:_thread和threading,_thread是低级模块,

  • 通过Web Workers,可以实现用操作系统级别的线程来跑JavaScript 多线程的Node.js 可以在Electron的Web Workers里使用Node.js的特性。要用的话,需把webPreferences中的nodeIntegrationInWorker选项设置为true const win = new BrowserWindow({ webPreferences: {