软件编程
位置:首页>> 软件编程>> java编程>> 使用javafx更新UI的方法

使用javafx更新UI的方法

作者:离离原上草77  发布时间:2023-05-02 17:32:30 

标签: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;
  }
 };
}
}

来源:https://blog.csdn.net/qq_41886200/article/details/104050685

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com