JavaFX TableView:显示已排序的项目+后台任务

时间:2017-03-22 13:07:59

标签: javafx tableview

我正在使用Javafx,在使用后台任务进行更新时,我正在努力获得一个已排序的表。在代码here中,可以独立运行,我在后台更新表。

我想要做的是这个表格会更新,并按时间顺序排列,因此较旧的列车时间显示在顶部,后面的列车显示在底部。该示例生成的时间与目的相反,以查看排序是否有效。

在我向表中添加并发更新之前,我运行了一些测试,我这样做的方法是调用:

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 个答案:

答案 0 :(得分:1)

我这样做的方法是通过后台任务更新ObservableList并将其用作&#34;源&#34;创建SortedList。然后,这个SortedList将作为&#34; items&#34;的来源。到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);
        }
    }
}
相关问题