为什么我的 javafx 标签在更改后没有显示?

Why is my javafx label not showing after it being changed?

我是 javafx 编程的新手,我不明白为什么我的 javafx 文本在更改后没有得到更新。 我想制作一个计时器,从 60 计数到 0。我正在尝试更改 timeCounter 文本,每一秒都过去了。 帮助将不胜感激!

这是我的控制器代码:

public class Controller {
    TimerUtil timerUtil;


    @FXML
    private Button startButton;
    @FXML
    private Text timeCounter;

    @FXML
    private Text pointCounter;

    @FXML
    private Circle circle;

    @FXML
    private void handleStartButtonClick(ActionEvent event) {
        timerUtil = new TimerUtil();

    }

    private class TimerUtil extends Pane {
        private int tmp = 60;
        private Timeline animation;


        public TimerUtil(){
            getChildren().add(timeCounter);
            animation = new Timeline(new KeyFrame(Duration.seconds(1), e -> timeLabel()));
            animation.setCycleCount(Timeline.INDEFINITE);
            animation.play();


        }

        private void timeLabel(){
            if(tmp > 0){
                tmp--;
            }
            timeCounter.setText(String.valueOf(tmp));
            System.out.println(tmp);

        }

    }
}

您的错误发生是因为标签已从其显示的父节点中静默删除:

  1. 您有 TimerUtil class 扩展窗格(我不知道为什么)。
  2. 您将 timeCounter 文本添加到 TimeUtil 窗格(同样,我不知道为什么)。
  3. 将 timeCounter 文本添加到 TimeUtil 窗格 将静默地将其从 FXML 加载程序注入它的父项 中删除。
  4. 您可能只显示 FXML 加载程序注入的父项。
  5. 您永远不会显示 TimerUtil 窗格。
  6. 因此,即使您的时间线正在更新文本,您也永远看不到它。

为了更好地理解您的错误,请阅读:

  • JavaFX - Why does adding a node to a pane multiple times or to different panes result in an error?

来自 Node javadoc:

If a program adds a child node to a Parent (including Group, Region, etc) and that node is already a child of a different Parent or the root of a Scene, the node is automatically (and silently) removed from its former parent.

修复错误后,基本概念对我有用。这是我根据您的代码创建的可运行示例:

import javafx.animation.*;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Timer extends Application {
    private int tmp = 60;
    private Text counter = new Text();
    private Timeline animation = new Timeline(
        new KeyFrame(Duration.seconds(1), e -> updateCounter())
    );

    @Override
    public void start(Stage stage) {
        animation.setCycleCount(Timeline.INDEFINITE);
        animation.play();

        StackPane layout = new StackPane(counter);
        layout.setPadding(new Insets(20));
        stage.setScene(new Scene(layout));
        stage.show();
    }

    private void updateCounter() {
        if (tmp > 0){
            tmp--;
        } else {
            animation.stop();
        }
        counter.setText(String.valueOf(tmp));
        System.out.println(tmp);
    }

    public static void main(String[] args) {
        launch(args);
    }
}