JavaFX在ui线程更新界面

发布时间 2023-10-27 20:43:56作者: .L1nk

问题:如何让JavaFX程序在运行的时候能动起来?

描述:JavaFX是单线程的,当点击Button执行的时候整个窗口会卡主,必须要等待程序执行完毕之后才能在页面中响应结果,这就是单线程带来的问题
如果不是通过ui线程去更新界面还会导致程序报错:Exception in thread "JavaFX Application Thread" java.lang.ArrayIndexOutOfBoundsException
主界面

package org.example;

import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("测试测试");
        Parent parent = FXMLLoader.load(getClass().getResource("../../1111.fxml"));
        Scene scene = new Scene(parent);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

控制器

package org.example;

import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;

/**
 * author:  chenqiaonian
 * version: 1.0
 * describe:
 */
public class Controller {

    @FXML
    private TextArea info;

    @FXML
    public void exec() {
        new Demo(info).run();
    }
}

功能实现类

package org.example;

import javafx.scene.control.TextArea;

/**
 * author:  chenqiaonian
 * version: 1.0
 * describe:
 */
public class Demo {
    private TextArea info;

    public Demo(TextArea info) {
        this.info = info;
    }

    public void run() {
        for (int i = 0; i <= 20; i++) {
            info.appendText("当前数值:" + i + "\n");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

此时运行程序点击button时窗口界面只有等待循环彻底结束后才能够更新ui界面

解决方案:通过ui线程去更新javafx界面

事件类继承Runnable类,在run方法中写逻辑代码

package org.example;

import javafx.scene.control.TextArea;

/**
 * author:  chenqiaonian
 * version: 1.0
 * describe:
 */
public class Test implements Runnable {

    private TextArea info;

    public Test(TextArea info) {
        this.info = info;
    }

    @Override
    public void run() {
        for (int i = 0; i <= 20; i++) {
            info.appendText("当前数值:" + i + "\n");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

更新界面,此时就能发现javafx的窗口是实时更新的

package org.example;

import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.scene.control.TextArea;

/**
 * author:  chenqiaonian
 * version: 1.0
 * describe:
 */
public class Controller {

    @FXML
    private TextArea info;

    @FXML
    public void exec() {
        Platform.runLater(() -> {
            new Thread(new Test(info)).start();
        });
    }
}