【问题标题】:Populate control without flooding FXThread填充控件而不淹没 FXThread
【发布时间】:2016-05-21 14:08:12
【问题描述】:

我有以下情况: 包含很多行的大文件(约 100k,来自服务器的日志)。该文件中的每一行都应该被解析、过滤并显示在 UI 上。

要从文件中读取数据,我使用BufferedReader,读取行,解析它并准备显示。它在不同的线程 (THREAD-1) 上运行并填充 BlockingQueue。在另一个线程 (THREAD-2) 中运行 UIUpdater - 它的目的是从队列中获取行批处理并运行以下内容:

Platform.runLater(() -> logArea.append(batchedLine)); 

显然,FX Thread 泛滥并且 UI 冻结。 所以,问题是:我可以从哪里获得有关解决此问题的模式/最佳实践的信息?

【问题讨论】:

    标签: java multithreading javafx javafx-8


    【解决方案1】:

    这实际上取决于您要填充的控件。

    向场景图中添加大量节点的成本很高,因此会很慢(例如将Text 对象放入任何容器中)。

    我建议使用最初设计用于显示大量数据的控件,例如 ListView

    在示例中,即使在 ListView 更新期间,Button 也会响应。

    Main.java

    public class Main extends Application {
    
        @Override
        public void start(Stage primaryStage) {
    
            HBox root = new HBox();
            Scene scene = new Scene(root, 700, 400, Color.WHITE);
    
            TableView<Person> personsTable = new TableView<Person>();
    
            TableColumn<Person, String> nameCol = new TableColumn<Person, String>("Name");
            nameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
            personsTable.getColumns().add(nameCol);
    
            ObservableList<Person> persons = FXCollections.observableArrayList();
    
            Thread th = new Thread(new Runnable() {
    
                @Override
                public void run() {
                    for (int i = 0; i < 100000; i++) {
                        Person person = new Person();
                        person.setName("Name" + i);
                        person.setAddress("Address" + i);
                        person.setCountry("Country" + i);
                        person.setCourse("Course" + i);
                        persons.add(person);
                        try {
                            Thread.sleep(5);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
    
                    }
    
                }
            }) ;
    
            th.start();
    
            personsTable.setItems(persons);
    
            Button b = new Button();
            b.setOnAction(new EventHandler<ActionEvent>() {
    
                @Override
                public void handle(ActionEvent event) {
                    System.out.println("I am printing independently of Person update!");
    
                }
            });
            root.getChildren().addAll(personsTable, b);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    Person.java

    public class Person {
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getCountry() {
            return country;
        }
    
        public void setCountry(String country) {
            this.country = country;
        }
    
        public String getCourse() {
            return course;
        }
    
        public void setCourse(String course) {
            this.course = course;
        }
    
        private String name;
        private String address;
        private String country;
        private String course;
    
    }
    

    用户 jewelsea 在 lgging 上取得了很好的成绩 example。只需稍加调整即可解决您的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-17
      • 2017-01-27
      • 1970-01-01
      相关资源
      最近更新 更多