我正在尝试编写一个简单的JavaFx程序,它假设检查时间并且每隔一小时做一些事情(起初只更改标签中的文本)。但我不断检查时间有问题。我正在使用Calendar类。 如果我写一个while(true)循环,程序启动但不做任何事情。 我应该使用线程吗? 我知道这可能是微不足道的问题,但我无法弄清楚,我在这方面有点新鲜; p
谢谢大家的帮助(我不知道我是否应该在下面回复或编辑这篇文章)。 我设法创建了自己的版本,我根据链接,你给了我。
public class Trening extends Application {
@Override
public void start(Stage primaryStage) {
Task<Integer> task = new Task<Integer>() {
@Override
protected Integer call() throws Exception {
Calendar tajm = Calendar.getInstance();
int hour = tajm.get(Calendar.HOUR_OF_DAY);
int minutes = 0;
updateMessage(Integer.toString(hour));
while (true) {
try {
minutes = 60 - tajm.get(Calendar.MINUTE);
Thread.sleep(minutes * 60000);
if (tajm.get(Calendar.HOUR_OF_DAY) != hour) {
hour = tajm.get(Calendar.HOUR_OF_DAY);
updateMessage(Integer.toString(hour));
} else {
}
} catch (InterruptedException ie) {
//System.err.print("...");
}
}
}
};
Label btn = new Label();
btn.textProperty().bind(task.messageProperty());
new Thread(task).start();
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("...");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
* main() serves only as fallback in case the application can not be
* launched through deployment artifacts, e.g., in IDEs with limited FX
* support. NetBeans ignores main().
*
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}}
就像我说我对编程很新,所以我很欣赏每一条建议。 非常感谢你的帮助,如果你对我所写的内容有任何建议,我不介意; p
抱歉,我没有将你的答案标记为有用,但我的声誉太低了......
答案 0 :(得分:2)
这是一种方法。
首先,封装你的周期性任务。
public static class MyPeriodicTask implements Runnable {
public void run() {
boolean fullHour = ... // determine somehow
if (fullHour) {
Platform.runLater(new Runnable() {
public void run() {
// Modify label here
}
});
}
}
}
注意Platform.runLater()
调用,传递Runnable
的这些保证将由JavaFX应用程序线程执行,您可以在其中安全地与GUI交互。
然后使用an ExecutorService
定期运行您的任务
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
executorService.scheduleAtFixedRate(new MyPeriodicTask(), 1, 1, TimeUnit.MINUTES);
这将在每分钟(初始延迟1分钟后)运行您的任务。
但如果您认真对待JavaFX,那么我认为您应该至少阅读Concurrency in JavaFX。
答案 1 :(得分:0)
这应该让你开始,请注意我使用了服务。任务可能会更好。 自从我编写Java以来已经有一段时间了但是通过跟随this guide,我能够快速创建下面的示例。
它还使用了日历库,我希望你发现它很有用。
import javafx.application.*;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.EventHandler;
import java.util.Calendar;
import java.util.Date;
public class StackOverflow_001 <T extends Comparable<T>> extends Application {
public static void main(String[] args) {
launch(args); // Launches the application
}
// A simple service with an internal clock.
private static class HourService extends Service<Date>
{
private Calendar calendar;
public final void setCalendarInstance(Calendar c)
{
calendar = c;
}
@Override
protected Task<Date> createTask() {
return new Task<Date>() {
protected Date call()
{
int secondsdelay = 5;
Date timeStarted = calendar.getTime();
Date timeEnd = new Date(timeStarted.getTime() + 1000 * secondsdelay );//* 60 * 60);
while( timeEnd.after(calendar.getTime()) )
{
try {
System.out.println("---");
System.out.println("Time: " + calendar.getTime());
System.out.println("End: " +timeEnd);
Thread.sleep(500);
calendar = Calendar.getInstance();
} catch (InterruptedException e) {
if (isCancelled()) {
updateMessage("Cancelled");
break;
}
}
}
System.out.println("Service ended.");
return timeEnd;
}
};
}
}
// Sets up everything and creates the window.
@Override
public void start(Stage primaryStage) throws Exception {
final VBox root = new VBox();
primaryStage.setScene(new Scene(root, 800, 600));
final Button btn1 = new Button();
btn1.setText(Calendar.getInstance().getTime().toString());
root.getChildren().add(btn1);
final HourService hservice = new HourService();
hservice.setCalendarInstance(Calendar.getInstance());
hservice.setOnSucceeded(new EventHandler<WorkerStateEvent>() { // Anonymous
@Override
public void handle(WorkerStateEvent t) {
btn1.setText(Calendar.getInstance().getTime().toString());
hservice.restart();
}
});
hservice.start();
primaryStage.show();
}
}