在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,此时只有背景显示,没有其他内容。
- 大多数情况下您不需要直接从
Thread
扩展,因为 JavaFX 有类似 Timeline
的东西可以充当计时器。如果您认为有必要(由于您未指定的其他原因),拥有 Time
class 是完全可以的。
- 从
Thread
扩展并创建另一个 Thread
绝对没有必要。当 Time
class 扩展 Thread
时,它本身已经是 Thread
.
- 您正在
Time
中创建 Main
的新实例。 Main
应该创建 Time
并将其自身传递给 Time
,否则 Time
将不会持有原始 Main
对象的引用。
- 我认为即使您解决了#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
}
}
我遇到了 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,此时只有背景显示,没有其他内容。
- 大多数情况下您不需要直接从
Thread
扩展,因为 JavaFX 有类似Timeline
的东西可以充当计时器。如果您认为有必要(由于您未指定的其他原因),拥有Time
class 是完全可以的。 - 从
Thread
扩展并创建另一个Thread
绝对没有必要。当Time
class 扩展Thread
时,它本身已经是Thread
. - 您正在
Time
中创建Main
的新实例。Main
应该创建Time
并将其自身传递给Time
,否则Time
将不会持有原始Main
对象的引用。 - 我认为即使您解决了#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
}
}