2017-03-22 58 views
0

我正在使用Javafx,並且在使用後臺任務進行更新時,我正努力獲取已排序的表。在代碼here中,可以獨立運行,我在後臺更新表格。JavaFX TableView:顯示排序項目+後臺任務

我想要做的是該表得到更新,並保持按時間順序排序,所以老火車時間出現在頂部,而後來的火車時間出現在底部。該示例生成的時間與目的相反,以查看排序是否有效。

我運行一些測試之前我添加併發更新的表,我會做到這一點的方法是調用:

private final ObservableList<StationBoardLine> data = FXCollections.observableArrayList(
     new StationBoardLine("RE", "17:14", "Basel Bad Bf", "Basel SBB", "+3", "RE 5343")); 
SortedList<StationBoardLine> sorted = new SortedList<>(data, new DelayComparator()); 
table.setItems(sorted); 

不過,現在我沒有設定的項目,但是使用的背景任務連同ReadOnlyObjectPropertyReadOnlyObjectWrapper附加到它。

所以,我的問題是,我怎樣才能確保項目被添加,列表仍然是有序的?我嘗試瞭解是否可以在電話Platform.runLater內重新排列列表,但似乎不起作用。

更新表,並設置表格的任務之間的聯繫是在這裏:

table.itemsProperty().bind(task.partialResultsProperty()); 

感謝您的幫助,

蓋爾德

回答

1

我會做的方式是通過更新由後臺任務ObservableList並將其用作創建SortedList的「源」。這SortedList然後將作爲TableView的「項目」的來源。

的一般結構是:

public class MyClass { 

    private TableView<T> tableView = new TableView; 
    private ObservableList<T> sourceList = FXCollections.observableArrayList(); 

    public MyClass() { 
     ... 
     SortedList<T> sortedList = new SortedList<>(sourceList, new MyComparator()); 
     tableView.setItems(sortedList); 

     ... 

     new Task<Void> { 
      protected Void call() { 
      ... // Some background data fetch 
      Platform.runLater(() -> sourceList.add(data)); 
      return null; 
      } 
     }; 
    } 
} 

對於您的情況,我會的東西,你已經走了。因此,我將使用由Task#getPartialResults()返回的列表,而不是創建一個新的ObservableList作爲SortedList的源。

DelayComparator使用延遲值來比較並顯示TableView中的數據。

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.collections.transformation.SortedList; 
import javafx.concurrent.Task; 
import javafx.scene.Scene; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.Stage; 

import java.util.Comparator; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class App extends Application { 

    private TableView<StationBoardLine> table = new TableView<>(); 
    private final ExecutorService exec = Executors.newSingleThreadExecutor(); 

    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage stage) { 
     BorderPane root = new BorderPane(); 
     Scene scene = new Scene(root, 800, 600); 

     table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); 
     table.setEditable(true); 

     TableColumn typeCol = getTableCol("Type", 10, "type"); 
     TableColumn departureCol = getTableCol("Departure", 30, "departure"); 
     TableColumn stationCol = getTableCol("Station", 200, "station"); 
     TableColumn destinationCol = getTableCol("Destination", 200, "destination"); 
     TableColumn delayCol = getTableCol("Delay", 20, "delay"); 
     TableColumn trainName = getTableCol("Train Name", 50, "trainName"); 

     table.getColumns().addAll(
       typeCol, departureCol, stationCol, destinationCol, delayCol, trainName); 

     root.setCenter(table); 

     PartialResultsTask task = new PartialResultsTask(); 
     SortedList<StationBoardLine> sorted = new SortedList<>(task.getPartialResults(), new DelayComparator()); 
     table.setItems(sorted); 
     exec.submit(task); 

     stage.setTitle("Swiss Transport Delays Board"); 
     stage.setScene(scene); 
     stage.show(); 
    } 

    private TableColumn getTableCol(String colName, int minWidth, String fieldName) { 
     TableColumn<StationBoardLine, String> typeCol = new TableColumn<>(colName); 
     typeCol.setMinWidth(minWidth); 
     typeCol.setCellValueFactory(new PropertyValueFactory<>(fieldName)); 
     return typeCol; 
    } 

    static final class DelayComparator implements Comparator<StationBoardLine> { 

     @Override 
     public int compare(StationBoardLine o1, StationBoardLine o2) { 
      return o1.getDelay().compareTo(o2.getDelay()); 
     } 

    } 

    public class PartialResultsTask extends Task<Void> { 

     private ObservableList<StationBoardLine>partialResults = FXCollections.observableArrayList(); 
     public final ObservableList<StationBoardLine> getPartialResults() { 
      return partialResults; 
     } 

     @Override protected Void call() throws Exception { 
      System.out.println("Creating station board entries..."); 
      for (int i=5; i >= 1; i--) { 
       Thread.sleep(1000); 
       if (isCancelled()) break; 
       StationBoardLine l = new StationBoardLine(
         "ICE", "16:" + i, "Basel Bad Bf", "Chur", String.valueOf(i), "ICE 75"); 
       Platform.runLater(() -> partialResults.add(l)); 
      } 
      return null; 
     } 
    } 

    public static final class StationBoardLine { 
     private final SimpleStringProperty type; 
     private final SimpleStringProperty departure; 
     private final SimpleStringProperty station; 
     private final SimpleStringProperty destination; 
     private final SimpleStringProperty delay; 
     private final SimpleStringProperty trainName; 

     StationBoardLine(String type, 
         String departure, 
         String station, 
         String destination, 
         String delay, 
         String trainName) { 
      this.type = new SimpleStringProperty(type); 
      this.departure = new SimpleStringProperty(departure); 
      this.station = new SimpleStringProperty(station); 
      this.destination = new SimpleStringProperty(destination); 
      this.delay = new SimpleStringProperty(delay); 
      this.trainName = new SimpleStringProperty(trainName); 
     } 

     public String getType() { 
      return type.get(); 
     } 

     public SimpleStringProperty typeProperty() { 
      return type; 
     } 

     public void setType(String type) { 
      this.type.set(type); 
     } 

     public String getDeparture() { 
      return departure.get(); 
     } 

     public SimpleStringProperty departureProperty() { 
      return departure; 
     } 

     public void setDeparture(String departure) { 
      this.departure.set(departure); 
     } 

     public String getStation() { 
      return station.get(); 
     } 

     public SimpleStringProperty stationProperty() { 
      return station; 
     } 

     public void setStation(String station) { 
      this.station.set(station); 
     } 

     public String getDestination() { 
      return destination.get(); 
     } 

     public SimpleStringProperty destinationProperty() { 
      return destination; 
     } 

     public void setDestination(String destination) { 
      this.destination.set(destination); 
     } 

     public String getDelay() { 
      return delay.get(); 
     } 

     public SimpleStringProperty delayProperty() { 
      return delay; 
     } 

     public void setDelay(String delay) { 
      this.delay.set(delay); 
     } 

     public String getTrainName() { 
      return trainName.get(); 
     } 

     public SimpleStringProperty trainNameProperty() { 
      return trainName; 
     } 

     public void setTrainName(String trainName) { 
      this.trainName.set(trainName); 
     } 
    } 
} 
+0

非常感謝您的快速回復。你的建議似乎有效:D –