0

I am working on a clock program in Java and I am unsure how to make the time update secondly. I have tried using a for loop with thread.sleep(1000); but that did not work. Also, if anybody knows how to stop the Stage from opening in white then having a small delay before turning black, that would be really appreciated.

Here is my code:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.paint.Color;
import javafx.scene.layout.HBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import java.text.DateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;

    public class Clock extends Application {

         @Override public void start(Stage stage) {

            DateFormat df = new SimpleDateFormat("EEE,MMM d yyyy - h:mm:ss a");
            Date date = new Date();
            String stringDate = df.format(date);

            Text text = new Text(10, 60, stringDate);
            text.setFont(Font.font ("Digital Dream Fat", 30f));
            text.setFill(Color.RED);

            HBox hbox = new HBox();

            Scene scene = new Scene(new Group(text));
            scene.setFill(Color.BLACK);

            stage.setScene(scene);
            stage.initStyle(StageStyle.UNDECORATED);
            stage.setWidth(710);
            stage.setHeight(80);
            stage.show(); 
        }

        public static void main(String[] args) {
            launch(args);
        }
    }
Herseept72
  • 25
  • 1
  • 6

2 Answers2

0

You have to setup a TimerTask and run it in a separate thead.

https://docs.oracle.com/javase/7/docs/api/java/util/TimerTask.html

TimerTask can't update the JavaFX Label text

Community
  • 1
  • 1
Timothy Truckle
  • 15,071
  • 2
  • 27
  • 51
0

First of all, you have to remember that UI's components are not thread-safe thus any update operations on the ui must be done within the ui's thread itself and not from background threads otherwise they will block the UI's thread.

To update it you can use thread safe mechanisms, one of them is Timeline class. Let's now implement it in your code.

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.paint.Color;
import javafx.scene.layout.HBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import java.text.DateFormat;
import java.util.Date;
import java.text.SimpleDateFormat;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.util.Duration;

    public class Clock extends Application {

         @Override public void start(Stage stage) {

            DateFormat df = new SimpleDateFormat("EEE,MMM d yyyy - h:mm:ss a");
            Date date = new Date();
            String stringDate = df.format(date);

            Text text = new Text(10, 60, stringDate);
            text.setFont(Font.font ("Digital Dream Fat", 30f));
            text.setFill(Color.RED);

            HBox hbox = new HBox();


            Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(0),
        new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent actionEvent) {
              Date update = new Date();
            String stringNewDate = df.format(update);
                    text.setText(stringNewDate);
            }
        }

        ), new KeyFrame(Duration.seconds(1)));
              timeline.setCycleCount(Animation.INDEFINITE);
        timeline.play(); // timeline.stop()

            Scene scene = new Scene(new Group(text));
            scene.setFill(Color.BLACK);

            stage.setScene(scene);
            stage.initStyle(StageStyle.UNDECORATED);
            stage.setWidth(710);
            stage.setHeight(80);
            stage.show(); 
        }

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

The sleep/pause part is controlled on this line .. new KeyFrame(Duration.seconds(1))) so every minute will be Duration.minutes(1), to stop it just take Timeline's instance then do timeline.stop()

Fevly Pallar
  • 3,059
  • 2
  • 15
  • 19