【发布时间】:2019-05-22 21:53:37
【问题描述】:
我正在尝试创建一个时钟,通过使用每秒更改的动态 UI 标签来监视程序的运行时间。我尝试使用以下代码,但不断收到空指针异常。此异常源于 JavaFX 应用程序线程上似乎为空的“时钟”标签,尽管已在控制器类中声明它。我还实现了 Platform.runlater 以确保标签更新将在 JavaFX 线程上运行,因为这是声明标签的地方,但是,它仍然抛出此异常。关于为什么会发生这种情况的任何指示?
控制器:
package GUI;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.Timer;
import java.util.TimerTask;
public class Controller implements Initializable {
int secondspassed = 0;
int minutespassed = 0;
int hourspassed = 0;
@FXML
private Label XPTrackerlabel;
@FXML
private ProgressBar XPTracker;
@FXML
private ComboBox Minelocation;
@FXML
private Label clock;
Timer timer = new Timer();
TimerTask ticktime = new TimerTask(){
public void run(){
secondspassed++;
if (secondspassed == 60){ secondspassed = 0; minutespassed++;}
else if (minutespassed == 60){ minutespassed = 0; hourspassed++;}
Platform.runLater(() -> clock.setText(hourspassed + ":" + minutespassed + ":" + secondspassed));
}
};
public void start() {
timer.scheduleAtFixedRate(ticktime, 1000, 1000);
}
public void PressButton(ActionEvent event){
Controller startclock = new Controller();
startclock.start();
System.out.println("Hello World");
}
@Override
public void initialize(URL url, ResourceBundle rb) {
Minelocation.getItems().addAll("North", "South", "North-East");
XPTracker.setProgress(0.5);
double XP = XPTracker.getProgress() * 100;
XPTrackerlabel.setText(XP + "%");
clock.setText(hourspassed + ":" + minutespassed + ":" + secondspassed);
}
}
FXML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane fx:id="UI" alignment="center" hgap="10" minHeight="300.0" minWidth="300.0" vgap="10" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="GUI.Controller">
<columnConstraints>
<ColumnConstraints />
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
<RowConstraints />
</rowConstraints>
<children>
<Button fx:id="start_btn" mnemonicParsing="false" onAction="#PressButton" stylesheets="@Style.css" text="Start" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="NEVER" GridPane.rowIndex="7" GridPane.valignment="CENTER" GridPane.vgrow="NEVER" />
<ComboBox fx:id="Minelocation" prefWidth="150.0" promptText="Select Area" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="2" GridPane.valignment="CENTER" />
<ProgressBar fx:id="XPTracker" prefWidth="200.0" progress="0.0" GridPane.columnIndex="1" GridPane.rowIndex="11" />
<Label fx:id="XPTrackerlabel" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="11" GridPane.valignment="CENTER" />
<Label fx:id="clock" GridPane.columnIndex="1" GridPane.halignment="CENTER" />
</children>
</GridPane>
错误:
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at GUI.Controller$1.lambda$run$0(Controller.java:38)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Unknown Source)
【问题讨论】:
-
在
Controller.java:38处抛出异常。请将此行标记为注释,以便我们知道哪一行是 38。 -
尝试在
initialize方法中初始化ticktime。 -
在
PressButton中创建Controller的新实例,而不是通过FXMLLoader加载。这可能是您问题的根源。 -
参见例如this question's answer了解更多信息。
标签: java javafx java-8 label scenebuilder