使用javafx更新UI的方法
作者:离离原上草77 发布时间:2023-05-02 17:32:30
使用javafx更新UI
JavaFx如果在子线程中更新UI,不论是task还是runable都会报错
java.lang.IllegalStateException: Not on FX application thread; currentThread =
这种情况可以使用下面的方法
1,Platform.runLater()
这个办法在当前线程不是javafx的线程中,比如runnable,thread这些的,直接调用即可,runLater()不是线程阻塞型的,在javafx的主线程完全清空或者说空闲的时候,它才会执行,
Platform.runLater(new Runnable() {
@Override
public void run() {
//更新JavaFX的主线程的代码放在此处
p.cancelProgressBar();
}
});
但是如果必须先执行这段代码怎么办呢,也有方法
1,future是个工作线程
他允许阻塞当前线程,执行线程中的代码,在拿到返回值后,才会顺序执行
// 定义一个FutureTask,然后 Plateform.runLater() 这个futuretask
final FutureTask<String> query = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
// 新建一个窗口(方法中将创建stage)
VcodeController vc = new VcodeController();
return vc.show(url4vcode);
}
});
Platform.runLater(query); // 重点
String vcode = query.get(); // 这样就能获取返回值
System.out.println(vcode);
2,利用 CountDownLatch,直接阻塞当前的主线程,执行相关代码业务
/**
* Runs the specified {@link Runnable} on the
* JavaFX application thread and waits for completion.
*
* @param action the {@link Runnable} to run
* @throws NullPointerException if {@code action} is {@code null}
*/
public static void runAndWait(Runnable action) {
if (action == null)
throw new NullPointerException("action");
// run synchronously on JavaFX thread
if (Platform.isFxApplicationThread()) {
action.run();
return;
}
// queue on JavaFX thread and wait for completion
final CountDownLatch doneLatch = new CountDownLatch(1);
Platform.runLater(() -> {
try {
action.run();
} finally {
doneLatch.countDown();
}
});
try {
doneLatch.await();
} catch (InterruptedException e) {
// ignore exception
}
}
3.使用task线程的返回值
task是javafx实现的ui线程,他实现了futureTask和worlker线程,所以它既可以当普通线程来使用,也可以重写返回值方法,实现ui界面的刷新
不过要说明的是,task的call方法,仍然是一个普通线程的方法,如果要实现在task中刷新ui界面,要在
scheduled(),succeeded(),running()任意一个方法中执行,就可以了,这样就实现了再task的线程中,刷新界面的功能
package com.yz.readismqtest1;
import javafx.concurrent.Task;
public class deda {
public static void main(String[] args) {
Task task = new Task() {
@Override
protected Object call() throws Exception {
//执行普通方法
return null;
}
@Override
protected void scheduled() {
//更新JavaFX的主线程的代码放在此处
super.scheduled();
}
@Override
protected void succeeded() {
//更新JavaFX的主线程的代码放在此处
super.succeeded();
}
@Override
protected void running() {
//更新JavaFX的主线程的代码放在此处
super.running();
}
};
}
}
JavaFX的并发编程与UI更新
JavaFX并发编程与UI更新
项目需求
根据项目需要,进行设备的并发测试,同时需要在界面上实时展示测试的结果
涉及到的技术
1、使用Observer的方式实现多个对象之间的通信(观察者模式)
2、因为UI只有一个,需要在较短时间内接收并显示大量的数据,所以使用了javafx.concurrent
3、线程池pool,减少对象的资源占用
上述技术的使用参考了大量的网络资源和书籍内容,再次不进行一一列举,感谢各位作者。
核心代码
// 1、从线程池中获取对象
ObjectPoolDrawUIService objPool = ObjectPoolDrawUIService.getInstance();
DrawUIService obj = (DrawUIService)objPool.getObject();
// 2、对象的初始化 produceCaseResult是需要更新的数据内容 ,i是行号信息,放在Object[]中进行传递
obj.init(new Object[]{produceCaseResult,i}, new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
Object[] objArray = (Object[])t.getSource().getValue();
testDetailList.set((int) objArray[1], (ProduceCaseResult)objArray[0]);
// 4、因为是在线程中执行,所以 returnObject代码不能跟在obj.restart后面,会导致被很快的restart
objPool.returnObject(obj);
}
});
// 3、执行
obj.restart(); // 因为是从pool中获取,可能已经执行完毕,所以restart
以上代码中需要特别注意,代码4的位置,以下代码为javafx.concurrent的核心代码
public class DrawUIService extends Service<Object[]>{
Object[] showData = {null,null};
public void init(Object[] showData, EventHandler<WorkerStateEvent> eventHandler) {
this.showData = showData;
setOnSucceeded(eventHandler);
}
@Override
protected Task<Object[]> createTask() {
return new Task<Object[]>() {
@Override
protected Object[] call() throws Exception {
return showData;
}
};
}
}
来源:https://blog.csdn.net/qq_41886200/article/details/104050685
猜你喜欢
- 什么是死锁我们先看看这样一个生活中的例子:在一条河上有一座桥,桥面较窄,只能容纳一辆汽车通过,无法让两辆汽车并行。如果有两辆汽车A和B分别由
- 最近我在考虑如何远程控制tomcat的启动和关机,最后是有友好的界面,能够实现一键式操作的,这样会肯定是会很方便的,网上找了半天,没找到,有
- 前言JDK 1.5 之前 synchronized 的性能是比较低的,但在 JDK 1.5 中,官方推出一个重量级功能 Lock,一举改变了
- 1. 理解abstract:抽象的2. 作用abstract可以用来修饰类、方法。不能用abstract修饰变量、代码块、构造器。不能用ab
- 前言自从用了SpringBoot,个人最喜欢的就是SpringBoot的配置文件了,和Spring比起SpringBoot更加灵活,修改的某
- 如果你发现在一个接口使用有如下定义方法: public String[] getParameters();那么你应该认
- 前言本文是精讲RestTemplate第7篇,前篇的blog访问地址如下:RestTemplate在Spring或非Spring环境下使用精
- 普通的excel列表,easyexcel读取是没有什么问题的。但是,如果有合并单元格,那么它读取的时候,能获取数
- 先贴代码,后面做一些简单说明:public static string sendPostHttpRequest_2(string url,
- 一、链表的介绍什么是链表链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结
- EasyTouch摇杆插件使用,先给大家展示下效果图:Demo展示双指缩放在电脑端无法掩饰,竖屏将就看看吧;插件名叫EasyTouch,有需
- 阅读提示 具有mybatis基础,熟练使用mybatis-plus。概述 我们都知道,mybatis-plus是一个mybatis的增强
- 记得我在以前找工作的经历中,遇到过一个面试官问过我一个很基础的问题。问题是:有一个List中有10个元素,我现在想从中删除3个元素,请问怎么
- 前言毕业季来临,很多小伙伴在忙于考公或者准备研究生复试等工作,因此从网上下载或者购买了源码。源码在本地运行成功之后,想要稍微修改一下,结果发
- 本文实例为大家分享了Unity封装延时调用定时器的具体代码,供大家参考,具体内容如下封装一个延时调用定时器类using System.Col
- 本文研究的主要是优化MyBatis配置文件中的配置的相关内容,具体介绍如下。一、连接数据库的配置单独放在一个properties文件中之前,
- Mybatis的Dao层实现传统开发方式1、编写UserDao接口public interface UserMapper {public L
- 前言日常开发中,我们可能会碰到需要进行防重放与操作幂等的业务,本文记录SpringBoot实现简单防重与幂等防重放,防止数据重复提交操作幂等
- 本文实例讲述了C#基于QRCode实现动态生成自定义二维码图片功能。分享给大家供大家参考,具体如下:二维码早就传遍大江南北了,总以为它是个神
- 方法1:import java.net.HttpURLConnection;import java.net.URL;import org.j