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 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();
            }
        };

    }
}

 

2方法的来源在这里https://blog.csdn.net/u010061897/article/details/69358246

你可能感兴趣的:(javafx线程,javafx)