在JavaFX中的指定时间显示text/shape

Display text/shape at a specified time in JavaFX

我遇到了 javaFX 的问题。 我想每 1000 毫秒在 App Window 中显示时间。

public class Main extends Application {

StackPane root = new StackPane();
Time time;
Text t1;
@Override
public void start(Stage primaryStage) throws Exception{
    root.setStyle("-fx-background-color: #00FF00");
    primaryStage.setTitle("My App");
    primaryStage.setScene(new Scene(root, 1000, 800));
    primaryStage.show();
    checkTime();


    primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
        @Override
        public void handle(WindowEvent t) {
            Platform.exit();
            System.exit(0);
        }
    });
}


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

public void checkTime(){
    time = new Time();
    time.start();
}

public void displayTime(int hour, int minute, int second){
    t1= new Text(200, 50, hour + ":" + minute + ":" + second);
    root.getChildren().add(t1);
}


}

这是第二个 class:

package sample;


import java.util.Calendar;

public class Time extends Thread {

Thread t;
public int hour;
public int minute;
public int second;
Calendar calendar;
Main main = new Main();


Time() {
}

public void run() {
    for (; ; ) {
        try {
            getTime();
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
    }
}

public void start() {
    t = new Thread(this);
    t.start();

}

public void getTime() {
    calendar = Calendar.getInstance();
    hour = calendar.get(Calendar.HOUR);
    minute = calendar.get(Calendar.MINUTE);
    second = calendar.get(Calendar.SECOND);
    System.out.println(hour + ":" + minute + ":" + second);
    main.displayTime(hour, minute, second);

}


}

我希望它以类似于数字时钟的方式工作。在项目的下一阶段中,我将想像使用其他 2D 图形一样使用这种方式。

此时,打开应用程序后,在控制台中花费的时间是正确的。但是,我希望在应用程序中显示完全相同的时间window,此时只有背景显示,没有其他内容。

  1. 大多数情况下您不需要直接从 Thread 扩展,因为 JavaFX 有类似 Timeline 的东西可以充当计时器。如果您认为有必要(由于您未指定的其他原因),拥有 Time class 是完全可以的。
  2. Thread 扩展并创建另一个 Thread 绝对没有必要。当 Time class 扩展 Thread 时,它本身已经是 Thread.
  3. 您正在 Time 中创建 Main 的新实例。 Main 应该创建 Time 并将其自身传递给 Time,否则 Time 将不会持有原始 Main 对象的引用。
  4. 我认为即使您解决了#3,您也肯定会在运行时遇到一些异常。您正在通过非 JavaFX 应用程序线程(即您的 Time class 线程)直接修改场景图。此外,每个 Time 周期都会创建一个新的 Text 对象,因此即使没有例外,这些 Text 对象也会相互重叠。

如果您出于其他特殊原因想要保留 Time class,那么通常您应该这样做:

public class Main extends Application {
    StackPane root = new StackPane();
    Time time;
    Text t1 = new Text(); // Instantiates only once

    @Override
    public void start(Stage primaryStage) throws Exception{
        root.setStyle("-fx-background-color: #00FF00");
        primaryStage.setTitle("My App");
        primaryStage.setScene(new Scene(root, 1000, 800));
        primaryStage.show();

        root.getChildren().add(t1);

        checkTime();


        primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent t) {
                Platform.exit();
                System.exit(0);
            }
        });
    }


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

    public void checkTime(){
        time = new Time(this); // Pass ownself into Time
        time.start();
    }

    public void updateTime(int hour, int minute, int second){
        Platform.runLater(() -> t1.setText(200, 50, hour + ":" + minute + ":" + second));
    }
}
public class Time extends Thread {
    //Thread t; // Not needed
    public int hour;
    public int minute;
    public int second;
    Calendar calendar;
    Main main; // Don't instantiate

    // Pass in the main object
    Time(Main main) {
        this.main = main;
    }

    public void run() {
        for (; ; ) {
            try {
                getTime();
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
        }
    }

    // This is not needed, Time class has its own start() method, which will call its run() method.
    //public void start() {
    //    t = new Thread(this);
    //    t.start();
    //}

    public void getTime() {
        calendar = Calendar.getInstance();
        hour = calendar.get(Calendar.HOUR);
        minute = calendar.get(Calendar.MINUTE);
        second = calendar.get(Calendar.SECOND);
        System.out.println(hour + ":" + minute + ":" + second);
        main.updateTime(hour, minute, second); // Update main
    }
}