我有一个 javafx.concurrent.Task 在后台运行一些代码并使用 java.util.logging.Logger 来提供有关其状态的信息。我需要在主线程的 UI 中显示此日志条目。我怎样才能做到这一点?
这是我制作的一个简单的玩具项目,用于解决上下文中的问题
@Override
public void start(Stage primaryStage) {
ListView<String> list = new ListView<>();
final ObservableList<String> items =FXCollections.observableArrayList ();
list.setItems(items);
Task<String> task = new Task<String>() {
@Override
protected String call() throws Exception {
doStuff();
return "yey";
}
};
new Thread(task).start();
Scene scene = new Scene(list, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
private void doStuff() {
for (int i=0;i<10;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger("LoggerUI").log(Level.INFO, "error");
}
Logger.getLogger("LoggerUI").log(Level.SEVERE, "whatever");
}
[...]
}
我试过这个,但它不起作用
public class LoggerUI extends Application {
@Override
public void start(Stage primaryStage) {
System.out.println("UI"+ Thread.currentThread().getId());
ListView<String> list = new ListView<>();
final ObservableList<String> items =FXCollections.observableArrayList ();
list.setItems(items);
Logger.getLogger("LoggerUI").addHandler(new Handler() {
@Override
public void publish(LogRecord lr) {
System.out.println("publish()"+ Thread.currentThread().getId());
items.add(lr.getMessage());
}
@Override
public void flush() {
System.out.println("flush");
}
@Override
public void close() throws SecurityException {
System.out.println("close");
}
});
Task<String> task = new Task<String>() {
@Override
protected String call() throws Exception {
doStuff();
return "yey";
}
};
new Thread(task).start();
Scene scene = new Scene(list, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
private void doStuff() {
System.out.println("doStuff()"+ Thread.currentThread().getId());
for (int i=0;i<300;i++) {
final int j =i;
try {
Thread.sleep(30);
} catch (InterruptedException ex) {
Logger.getLogger("LoggerUI").log(Level.INFO, "error");
}
Platform.runLater(new Runnable() {
@Override
public void run() {
System.out.println("runLater()"+ Thread.currentThread().getId());
Logger.getLogger("LoggerUI").log(Level.SEVERE, "whatever" +j);
}
});
}
[..]
}
}
它显示前 20-30 个条目,然后停止更新 UI