翻译成UI记录器条目被停止使用时间更新(Logger entries translated to t

2019-09-22 06:14发布

我有一个在后台运行一些代码,并使用java.util.logging.Logger中提供有关其状态的信息javafx.concurrent.Task。 我需要显示在主线程的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-30th项,然后停下来更新UI

Answer 1:

更新:这不是真正的JavaFX问题,但Java日志的一个。

存储记录仪为变量,因为返回的记录器Logger.getLogger()一样的,每次都没有,它们被缓存,垃圾回收和东西。

private Logger logger = Logger.getLogger("LoggerUI");

和使用方法如下:

logger.addHandler(new Handler() { ... });

logger.log(Level.SEVERE, "whatever" +j);

另外,我建议移动Platform.runLater()调用publish()方法,使您的记录仪会从任何线程工作。



文章来源: Logger entries translated to the UI stops being updated with time