Saintasger
Saintasger

Reputation: 13

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

I'm new to javafx programming, and i dont understand why my javafx Text isn't getting updated, when it is changed. I want to make a timer, that counts from 60 to 0. I'm trying to change the timeCounter Text, for every second that has passed. Help would be appreciated!

Here's my controller code:

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);

        }

    }
}

Upvotes: 1

Views: 440

Answers (1)

jewelsea
jewelsea

Reputation: 159291

Your error occurs because the label has been silently removed from it's displayed parent node:

  1. You have your TimerUtil class extend Pane (I have no idea why).
  2. You add the timeCounter text to the TimeUtil pane (again, I have no idea why).
  3. Adding the timeCounter text to the TimeUtil pane will silently remove it from the parent which the FXML loader injected it into.
  4. You are probably only displaying the parent which the FXML loader injected.
  5. You are never displaying the TimerUtil pane.
  6. Therefore, even though the text is getting updated by your timeline, you never see it.

To better understand your error, read:

From the 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.

Once you fix your error, the basic concept works for me. Here is the runnable example I created from your code:

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);
    }
}

Upvotes: 3

Related Questions