填充控制而不会泛滥FXThread

时间:2016-05-21 14:08:13

标签: java multithreading javafx javafx-8

我有以下情况: 有大量行的大文件(~100k,来自服务器的日志)。应该在UI上解析,过滤和取消使用此文件中的每一行。

要从文件中读取数据,我使用BlockingQueue,读取行,解析它并准备消除。它在不同的线程(THREAD-1)上运行并填充UIUpdater。在另一个线程(THREAD-2)中运行Platform.runLater(() -> logArea.append(batchedLine)); - 它的目的是从队列中获取行批处理并运行以下行:

JButton

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

1 个答案:

答案 0 :(得分:0)

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

向场景图中添加大量节点非常昂贵,因此速度很慢(例如将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在抓取方面做得非常好example。只需很少的剪裁就可以解决您的问题。