我有以下情况: 有大量行的大文件(~100k,来自服务器的日志)。应该在UI上解析,过滤和取消使用此文件中的每一行。
要从文件中读取数据,我使用BlockingQueue
,读取行,解析它并准备消除。它在不同的线程(THREAD-1)上运行并填充UIUpdater
。在另一个线程(THREAD-2)中运行Platform.runLater(() -> logArea.append(batchedLine));
- 它的目的是从队列中获取行批处理并运行以下行:
JButton
显然,FX Thread泛滥和UI冻结。 所以,问题是:在哪里可以获得有关模式/最佳实践的信息以解决此问题?
答案 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;
}