在JavaFX中的指定时间显示文本/形状

时间:2018-05-22 00:07:22

标签: java javafx javafx-8

我遇到了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);
}


}

那是第二堂课:

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图形的方式使用这种方式。

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

1 个答案:

答案 0 :(得分:1)

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

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