我可以使用线程在JavaFX中设置标签文本吗?

我可以使用线程在JavaFX中设置标签文本吗?,java,multithreading,javafx,nullpointerexception,Java,Multithreading,Javafx,Nullpointerexception,我想在不点击任何按钮的情况下不断显示汽车的当前里程数,等等 螺纹类 package threads; import javafx.fxml.FXML; import javafx.scene.control.Label; import static controller.GameWindowController.*; public class MileageThread implements Runnable { @FXML Label mileageLabel; @Override

我想在不点击任何按钮的情况下不断显示汽车的当前里程数,等等

螺纹类

package threads;

import javafx.fxml.FXML;
import javafx.scene.control.Label;

import static controller.GameWindowController.*;

public class MileageThread implements Runnable {


@FXML
Label mileageLabel;

@Override
public void run() {
    {
        double time = 1;
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (NullPointerException | InterruptedException e) {
                e.printStackTrace();
            }
            getCar().setDistancePerSec((time * getCar().getCurrentCarSpeed()) / 3600);
            getCar().setCarMileage(getCar().getCarMileage() + getCar().getDistancePerSec());
            System.out.format("dziala %.3f km przebiegu %n", getCar().getCarMileage());
            mileageLabel.setText(String.valueOf(getCar().getCarMileage()));
        }
    }
}
}

凭此记录,我收到:

Exception in thread "Thread-5" java.lang.NullPointerException
at threads.MileageThread.run(MileageThread.java:27)
这是我制作线程的课程:

package controller;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
import model.VehicleStatus;
import threads.MileageThread;
import vehicles.Car;

import java.net.URL;
import java.util.ResourceBundle;

public class GameWindowController extends Thread implements Initializable, Runnable {

@FXML
ImageView smoke;

@FXML
private Label speedLabel, mileageLabel;

static Car car;

static {
    car = new Car() {
    };
}

public void accelerationButtonPushed(ActionEvent event) throws InterruptedException {
    car.accelerate();

    speedLabel.setText(String.valueOf(car.getCurrentCarSpeed()));

    smoke.setFitHeight(smoke.getX() + car.getCurrentCarSpeed());
    smoke.setFitWidth(smoke.getY() + car.getCurrentCarSpeed());

    System.out.println(car.getCurrentCarSpeed());
    System.out.println(car.getCarMileage());
    System.out.println(car.getFuel());
    System.out.println(car.getStatus());
}

public void stopCarButtonPushed(ActionEvent event) throws InterruptedException {

    if (car.getCurrentCarSpeed() == 0) {
        System.out.println("Silnik zgasl!");
    }
    car.stop();

    speedLabel.setText(String.valueOf(car.getCurrentCarSpeed()));
    smoke.setFitHeight(smoke.getX() + car.getCurrentCarSpeed());
    smoke.setFitWidth(smoke.getY() + car.getCurrentCarSpeed());

    System.out.println(car.getCurrentCarSpeed());
    System.out.println(car.getCarMileage());
    System.out.println(car.getFuel());
    System.out.println(car.getStatus());
}

public void startButtonPushed(ActionEvent event) throws InterruptedException {
    if (car.getStatus() != VehicleStatus.MOVING) {
        car.start();
    } else System.out.println("Samochod juz jest na chodzie!");

    System.out.println("Status pojazdu: " + car.getStatus());
}

@FXML
public void initialize(URL location, ResourceBundle resources) {
    smoke.setFitHeight(1);
    smoke.setFitWidth(1);

    MileageThread mileageThread = new MileageThread();
    Thread mt = new Thread(mileageThread);
    mt.start();

}

public static Car getCar() {
    return car;
}
}

如果你在这里发现一些基本的错误或者我误解了你,我道歉


我使用的是场景生成器,我只想使用MileageThread将文本放在其中一个标签中。

如果要从JavaFX应用程序线程以外的线程修改用户界面,则必须在调用Platform.runLater时对其进行包装


只能从JavaFX应用程序线程修改JavaFX节点/控件等。

如果要从JavaFX应用程序线程以外的线程修改用户界面,必须将其包装在对Platform.runLater的调用中


只能从JavaFX应用程序线程修改JavaFX节点/控件等。

适合我的解决方案:

@FXML
    public void initialize(URL location, ResourceBundle resources) {
        PauseTransition wait = new PauseTransition(Duration.seconds(1));
    wait.setOnFinished((e) -> {
        mileageLabel.setText(String.valueOf(getCar().getCarMileage()));
        wait.playFromStart();
    });
    wait.play();
}

我希望有人能帮助我:

对我有效的解决方案:

@FXML
    public void initialize(URL location, ResourceBundle resources) {
        PauseTransition wait = new PauseTransition(Duration.seconds(1));
    wait.setOnFinished((e) -> {
        mileageLabel.setText(String.valueOf(getCar().getCarMileage()));
        wait.playFromStart();
    });
    wait.play();
}

我希望有人能帮上忙:

A演示这个问题也会有帮助。例如stopCarButtonPushed或Acceleration CarbuttonPushed。我在那里设置了speedLabel,它是我的速度表,但只有当按下按钮时它才会更新。我想显示波形,而无需按下按钮,例如,上面的线程,但我编写它的方式不起作用。假设适当的线程安全性,无论汽车如何更新,您可以使用定期更新标签的时间线。看,非常感谢。这篇文章帮助了我。我用了:PauseTransitionunrelated:摆脱所有这些静态…演示这个问题也会有帮助。比如在stopCarButtonPushed或accelerationCarButtonPushed中。我在那里设置了speedLabel,它是我的速度表,但只有当按下按钮时它才会更新。我想显示波形,而无需按下按钮,例如,上面的线程,但我编写它的方式不起作用。假设适当的线程安全性,无论汽车如何更新,您可以使用定期更新标签的时间线。看,非常感谢。这篇文章帮助了我。我用过:PauseTransitionunrelated:去掉所有的静态…Platform.runLater对我不起作用。我使用暂停转换。谢谢你的帮助:Platform.runLater对我不起作用。我使用暂停转换。谢谢你的帮助: