2017-03-22 59 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 –