2016-05-21 42 views
0

我有以下情況: 有大量行的大文件(〜100k,服務器日誌)。此文件中的每一行都應該在UI上進行解析,過濾和消除。填充控件而不淹沒FXThread

要從文件中讀取數據,我使用BufferedReader,讀取這些行,解析它併爲disaplying做準備。它運行在不同的線程(THREAD-1)上並填充BlockingQueue。在另一個線程(線程2)拼命地跑UIUpdater - 其目的是從隊列中獲取行批和運行的東西線這樣的:

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

顯然,FX線程洪水和UI是凍結。 所以,問題是:我可以在哪裏獲得有關解決此問題的模式/最佳實踐的信息?

回答

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上lgging。少量剪裁就可以解決你的問題。