使用javafx更新UI的方法

 更新时间:2021年07月08日 08:59:54   作者:离离原上草77  
这篇文章主要介绍了使用javafx更新UI的方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

使用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;
   }
  };
 }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java验证用户是否已经登录 java实现自动登录

    java验证用户是否已经登录 java实现自动登录

    这篇文章主要介绍了java验证用户是否已经登录,java实现自动登录,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • mybatis 多表关联mapper文件写法操作

    mybatis 多表关联mapper文件写法操作

    这篇文章主要介绍了mybatis 多表关联mapper文件写法操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • SpringBoot中@Scheduled实现服务启动时执行一次

    SpringBoot中@Scheduled实现服务启动时执行一次

    本文主要介绍了SpringBoot中@Scheduled实现服务启动时执行一次,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • Spring循环依赖正确性及Bean注入的顺序关系详解

    Spring循环依赖正确性及Bean注入的顺序关系详解

    这篇文章主要给大家介绍了关于Spring循环依赖的正确性,以及Bean注入的顺序关系的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-01-01
  • Java连接postgresql数据库的示例代码

    Java连接postgresql数据库的示例代码

    本篇文章主要介绍了Java连接postgresql数据库的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • java实现识别二维码图片功能方法详解与实例源码

    java实现识别二维码图片功能方法详解与实例源码

    这篇文章主要介绍了java实现识别二维码图片,java无法识别二维码情况下对二维码图片调优功能方法与实例源码,需要的朋友可以参考下
    2022-12-12
  • SpringBoot中优化if-else语句的七种方法

    SpringBoot中优化if-else语句的七种方法

    if-else语句是控制流程的基本工具,但过度使用会使代码变得复杂且难以维护,在SpringBoot , SpringCloud项目中,优化if-else结构变得尤为重要,本文将深入探讨七种策略,旨在减少SpringBoot , SpringCloud项目中 if-else的使用,需要的朋友可以参考下
    2024-07-07
  • java返回的List进行add操作报错

    java返回的List进行add操作报错

    本文主要介绍了java返回的List进行add操作报错,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • Spring零基础入门WebFlux响应式编程

    Spring零基础入门WebFlux响应式编程

    Spring 提供了两个并行堆栈,一种是基于带有 Spring MVC 和 Spring Data 结构的 Servlet API,另一个是完全反应式堆栈,它利用了 Spring WebFlux 和 Spring Data 的反应式存储库,这篇文章主要介绍了Spring-webflux 响应式编程,需要的朋友可以参考下
    2022-10-10
  • Java应用开源框架实现简易web搜索引擎

    Java应用开源框架实现简易web搜索引擎

    本篇文章主要介绍了Java应用开源框架实现简易web搜索引擎,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11

最新评论