Почему моя метка JavaFX помечена как нулевая, несмотря на то, что она объявлена ​​в потоке приложения JavaFX? - PullRequest
0 голосов
/ 23 декабря 2018

Я пытаюсь создать часы, которые отслеживают время выполнения программы, используя динамический ярлык пользовательского интерфейса, который меняется каждую секунду.Я попытался использовать следующий код, но продолжаю получать исключение нулевого указателя.Это исключение проистекает из метки «clock», которая кажется нулевой в потоке приложения 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)

1 Ответ

0 голосов
/ 23 декабря 2018

Оказывается, Itai был прав, по какой-то причине я подумал, что было бы неплохо создать новый экземпляр контроллера в Pressbutton, поэтому ошибка продолжала появляться.Просто наличие start () вместо создания нового экземпляра и вызов start () для решения этой проблемы!Спасибо за помощь.

Вот пересмотренный код:

пакет 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 clocker;


    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(() -> clocker.setText(hourspassed + ":" + minutespassed + ":" + secondspassed));
        }
    };

    public void start() {
        timer.scheduleAtFixedRate(ticktime, 1000, 1000);
    }

    public void PressButton(ActionEvent event){
        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 + "%");
        clocker.setText(hourspassed + ":" + minutespassed + ":" + secondspassed);
    }
}
...