使用javafx更新UI的方法

网友投稿 390 2022-12-29

使用javafx更新UI的方法

使用javafx更新UI

JavaFx如果在子线程中更新UI,不论是task还是runable都会报错

java.lang.IllegalStateException: Not on FX application thread; currentThread =

这种情kvrXN况可以使用下面的方法

1,Platform.runLater()

这个办法在当前线程不是javafx的线程中,比如runnable,thread这些的,直接调用即可,runLater()不是线程阻塞型的,在javafx的主线程完全清空或者说空闲的时候,它才会执行,

Platfhttp://orm.runLater(new Runnable() {

@Override

public void run() {

//更新JavaFX的主线程的代码放在此处

p.cancelProgressBar();

}

});

但是如果必须先执行这段代码怎么办呢,也有方法

1,future是个工作线程

他允许阻塞当前线程,执行线程中的代码,在拿到返回值后,才会顺序执行

// 定义一个FutureTask,然后 Plateform.runLater() 这个futuretask

final FutureTask query = new FutureTask(new Callable() {

@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() {

@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[] showData = {null,null};

public void init(Object[] showData, EventHandler eventHandler) {

this.showData = showData;

setOnSucceeded(eventHandler);

}

@Override

protected Task createTask() {

return new Task() {

@Override

protected Object[] call() throws Exception {

return showData;

}

};

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:网站访问API接口(网页api接口去哪里找)
下一篇:免费的语录数据api接口(免费的语录数据api接口是什么)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~