使用javafx更新UI的方法
使用javafx更新UI
JavaFx如果在子線程中更新UI,不論是task還是runable都會報(bào)錯
java.lang.IllegalStateException: Not on FX application thread; currentThread =
這種情況可以使用下面的方法
1,Platform.runLater()
這個辦法在當(dāng)前線程不是javafx的線程中,比如runnable,thread這些的,直接調(diào)用即可,runLater()不是線程阻塞型的,在javafx的主線程完全清空或者說空閑的時候,它才會執(zhí)行,
Platform.runLater(new Runnable() { @Override public void run() { //更新JavaFX的主線程的代碼放在此處 p.cancelProgressBar(); } });
但是如果必須先執(zhí)行這段代碼怎么辦呢,也有方法
1,future是個工作線程
他允許阻塞當(dāng)前線程,執(zhí)行線程中的代碼,在拿到返回值后,才會順序執(zhí)行
// 定義一個FutureTask,然后 Plateform.runLater() 這個futuretask final FutureTask<String> query = new FutureTask<String>(new Callable<String>() { @Override public String call() throws Exception { // 新建一個窗口(方法中將創(chuàng)建stage) VcodeController vc = new VcodeController(); return vc.show(url4vcode); } }); Platform.runLater(query); // 重點(diǎn) String vcode = query.get(); // 這樣就能獲取返回值 System.out.println(vcode);
2,利用 CountDownLatch,直接阻塞當(dāng)前的主線程,執(zhí)行相關(guān)代碼業(yè)務(wù)
/** * 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實(shí)現(xiàn)的ui線程,他實(shí)現(xiàn)了futureTask和worlker線程,所以它既可以當(dāng)普通線程來使用,也可以重寫返回值方法,實(shí)現(xiàn)ui界面的刷新
不過要說明的是,task的call方法,仍然是一個普通線程的方法,如果要實(shí)現(xiàn)在task中刷新ui界面,要在
scheduled(),succeeded(),running()任意一個方法中執(zhí)行,就可以了,這樣就實(shí)現(xiàn)了再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 { //執(zhí)行普通方法 return null; } @Override protected void scheduled() { //更新JavaFX的主線程的代碼放在此處 super.scheduled(); } @Override protected void succeeded() { //更新JavaFX的主線程的代碼放在此處 super.succeeded(); } @Override protected void running() { //更新JavaFX的主線程的代碼放在此處 super.running(); } }; } }
JavaFX的并發(fā)編程與UI更新
JavaFX并發(fā)編程與UI更新
項(xiàng)目需求
根據(jù)項(xiàng)目需要,進(jìn)行設(shè)備的并發(fā)測試,同時需要在界面上實(shí)時展示測試的結(jié)果
涉及到的技術(shù)
1、使用Observer的方式實(shí)現(xiàn)多個對象之間的通信(觀察者模式)
2、因?yàn)閁I只有一個,需要在較短時間內(nèi)接收并顯示大量的數(shù)據(jù),所以使用了javafx.concurrent
3、線程池pool,減少對象的資源占用
上述技術(shù)的使用參考了大量的網(wǎng)絡(luò)資源和書籍內(nèi)容,再次不進(jìn)行一一列舉,感謝各位作者。
核心代碼
// 1、從線程池中獲取對象 ObjectPoolDrawUIService objPool = ObjectPoolDrawUIService.getInstance(); DrawUIService obj = (DrawUIService)objPool.getObject(); // 2、對象的初始化 produceCaseResult是需要更新的數(shù)據(jù)內(nèi)容 ,i是行號信息,放在Object[]中進(jìn)行傳遞 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、因?yàn)槭窃诰€程中執(zhí)行,所以 returnObject代碼不能跟在obj.restart后面,會導(dǎo)致被很快的restart objPool.returnObject(obj); } }); // 3、執(zhí)行 obj.restart(); // 因?yàn)槭菑膒ool中獲取,可能已經(jīng)執(zhí)行完畢,所以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; } }; } }
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
MyBatis利用攔截器實(shí)現(xiàn)數(shù)據(jù)脫敏詳解
現(xiàn)代網(wǎng)絡(luò)環(huán)境中,敏感數(shù)據(jù)的處理是至關(guān)重要的,敏感數(shù)據(jù)包括個人身份信息、銀行賬號、手機(jī)號碼等,所以本文主要為大家詳細(xì)介紹了MyBatis如何利用攔截器實(shí)現(xiàn)數(shù)據(jù)脫敏,希望對大家有所幫助2023-11-11vue+ java 實(shí)現(xiàn)多級菜單遞歸效果
這篇文章主要介紹了vue+ java 實(shí)現(xiàn)多級菜單遞歸效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-12-12@RequiredArgsConstructor如何實(shí)現(xiàn)構(gòu)造器注入
這篇文章主要介紹了@RequiredArgsConstructor如何實(shí)現(xiàn)構(gòu)造器注入問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-09-09Spring Boot 2.0.0 終于正式發(fā)布-重大修訂版本
北京時間 2018 年 3 月 1 日早上,如約發(fā)布的 Spring Boot 2.0 在同步至 Maven 倉庫時出現(xiàn)問題,導(dǎo)致在 GitHub 上發(fā)布的 v2.0.0.RELEASE 被撤回2018-03-03