我有一个 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
更新:这实际上不是 JavaFX 问题,而是 java 日志记录问题。
将 Logger 存储到变量中,因为 Loggers 返回Logger.getLogger()
每次都不一样,它们被缓存、垃圾收集等等。
private Logger logger = Logger.getLogger("LoggerUI");
并使用如下:
logger.addHandler(new Handler() { ... });
logger.log(Level.SEVERE, "whatever" +j);
另外,我建议搬家Platform.runLater()
拨电至publish()
方法,因此您的记录器可以在任何线程中工作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)