如何获得自动排序TableView?

时间:2016-09-13 20:27:47

标签: javafx javafx-8

我有一个带有项目列表(事务)的TableView,并希望它进行排序,以便所有正值都高于负值。这是唯一的要求。

到目前为止我所拥有的:

expensesTableView.sortPolicyProperty().set(
    new Callback<TableView<Transaction>, Boolean>() {
    @Override
    public Boolean call(TableView<Transaction> param) {
        Comparator<Transaction> c = (a, b) -> {
            if (a.getValue().contains("-") ^ b.getValue().contains("-")) { //getValue() returns a String
                return a.getValue().contains("-") ? 1 : -1;
            }
            return 0;
        };
        FXCollections.sort(expensesTableView.getItems(), c);
        return true;
    };
});

这不是我的想法,我在网上发现了这个,所以不要问它是否是一种奇怪的方式来实现这一目标。真正的问题是,当添加/编辑/删除新项目时,表格不会自行排序。我需要点击标题3次然后它做我想要的。 如何才能获得始终正确排序的列表?

我尝试添加ChangeListener并对更改进行排序。但除此之外,这是一种丑陋的方式,它甚至不起作用......我在思想的最后。

1 个答案:

答案 0 :(得分:1)

比较器中的按位OR在我的测试中不起作用,因此我将其更改为正常值,并且它也没有检查列表中项目值的变化。

我想知道进行数字检查而不是字符串检查是否更有效,但负面数据仍然可以在下面排序,但我想转换可能会花费更多?

我在评论中对SortedList的第一个想法实际上与保持原始排序顺序有关,在用户更改排序后要恢复,因此不合适。

编辑添加:为了澄清,这是保持源列表排序以保持表列表排序的行为。

public class TestApp extends Application {

    private int c;
    private ObservableList<TestTransaction> sortedOL;
    private final Comparator<TestTransaction> comp = (TestTransaction a, TestTransaction b) -> {
        if (a.getValue().contains("-") || b.getValue().contains("-")) {
            return a.getValue().contains("-") ? 1 : -1;
        }
        return 0;
    };

    private TableView<TestTransaction> tableView;

    @Override
    public void start(Stage primaryStage) {

        ArrayList<TestTransaction> rawList = new ArrayList<>();

        for (int i = 1; i < 20; i++) {
            int v = i * 3;
            if (v % 2 > 0) {
                v = v * -1;
            }
            c = i;
            rawList.add(new TestTransaction(Integer.toString(v), "Item " + c));

        }

        sortedOL = FXCollections.observableArrayList(rawList);
        sortedOL.addListener((ListChangeListener.Change<? extends TestTransaction> c1) -> {
            if (c1.next() && (c1.wasAdded() || c1.wasRemoved())) {
                FXCollections.sort(sortedOL, comp);
            }
        });
        FXCollections.sort(sortedOL, comp);

        tableView = new TableView<>(sortedOL);

        TableColumn<TestTransaction,String> valCol = new TableColumn<>("Value");
        valCol.setCellValueFactory(new PropertyValueFactory("value"));
        TableColumn<TestTransaction,String> nameCol = new TableColumn<>("Name");
        nameCol.setCellValueFactory(new PropertyValueFactory("name"));
        tableView.getColumns().setAll(valCol, nameCol);

        BorderPane tpane = new BorderPane();

        Button btnAdd = new Button("Add");
        btnAdd.setOnAction(a -> {addTransaction();});

        ToolBar tb = new ToolBar(btnAdd);
        tpane.setTop(tb);

        tpane.setCenter(tableView);

        tpane.setPrefSize(600, 600);

        Scene scene = new Scene(tpane, 600, 600);

        primaryStage.setTitle("Test");
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    private void addTransaction() {
        c++;
        int v = (int) Math.floor(Math.random() * 50);
        if (v % 2 > 0) {
            v = v * -1;
        }
        sortedOL.add(new TestTransaction(Integer.toString(v), "New Item " + c));
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

public class TestTransaction {

    private String value;

    private String name;

    public TestTransaction(String value, String name) {
        this.value = value;
        this.name = name;
    }

    /**
     * @return the value
     */
    public String getValue() {
        return value;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

}

如果你想使用SortedList,意味着你可以内联比较器:

sortedOL = FXCollections.observableArrayList(rawList);
SortedList sorted = new SortedList(sortedOL, comp);
tableView = new TableView<>(sorted);