JavaFX TableView排序策略

时间:2014-08-26 14:58:59

标签: javafx tableview

我有一个tableview,它附有一个可观察的自定义类对象列表(类类型:SalesInvoiceNetSale)。表中的数据都很好。可观察列表中的最后一项是总计行(类类型:SalesInvoiceNetSaleTotal,它扩展了SalesInvoiceNetSale类)。如果用户尝试按列对表进行排序,我只希望让我的表不对数组中的最后一条记录进行排序。我发现另一个帖子几乎都在询问如何做同样的事情,但似乎无法解决这个问题,我怀疑这是我对Java 8的Lambda表达式的不了解。 TableView exclude bottom row (total) from sorting

public ObservableList<SalesInvoiceNetSale> applyTableTotalsToSalesInvoiceNetSaleList(ObservableList<SalesInvoiceNetSale> data, TableView table) {

    // Adds A Total Row To The Table View & Disables The Sort Policy 
    double netValueTotal = 0;
    double netDelivery = 0.0;
    double netOversize = 0.0;
    double netDeposit = 0.0;

    for (SalesInvoiceNetSale i : data) {
        netValueTotal += i.getNetValue();
        netDelivery += i.getNetShipping();
        netOversize += i.getNetOversize();
        netDeposit += i.getNetDeposit();
    }

    SalesInvoiceNetSaleTotal rowTotal = new SalesInvoiceNetSaleTotal();
    rowTotal.setNetValue(netValueTotal);
    rowTotal.setNetShipping(netDelivery);
    rowTotal.setNetDeposit(netDeposit);
    rowTotal.setNetOversize(netOversize);
    rowTotal.setLabel("Totals");

    data.add(rowTotal);

    table.sortPolicyProperty().set(t -> {
        Comparator<Row> comparator = (r1, r2)
                -> r1 == TOTAL ? 1 //TOTAL at the bottom
                : r2 == TOTAL ? -1 //TOTAL at the bottom
                : t.getComparator() == null ? 0 //no column sorted: don't change order
                : t.getComparator().compare(r1, r2); //columns are sorted: sort accordingly
        FXCollections.sort(table.getItems(), comparator);
        return true;
    });

    return data;

}

对JavaFX来说是一个新手,似乎无法通过排序策略的示例找到...

2 个答案:

答案 0 :(得分:9)

根据您的情况,您可以尝试这样的事情:

table.sortPolicyProperty().set(t -> {
    Comparator<SalesInvoiceNetSale> comparator = (r1, r2)
            -> r1 == rowTotal ? 1 //rowTotal at the bottom
            : r2 == rowTotal ? -1 //rowTotal at the bottom
            : t.getComparator() == null ? 0 //no column sorted: don't change order
            : t.getComparator().compare(r1, r2); //columns are sorted: sort accordingly
    FXCollections.sort(table.getItems(), comparator);
    return true;
});

如果你不明白这里发生了什么,快照没有lambda表达

table.sortPolicyProperty().set( new Callback<TableView<SalesInvoiceNetSale>, Boolean>() {
    @Override
    public Boolean call(TableView<SalesInvoiceNetSale> param) {
            Comparator<SalesInvoiceNetSale> comparator = new Comparator<SalesInvoiceNetSale>() {
                @Override
                public int compare(SalesInvoiceNetSale r1, SalesInvoiceNetSale r2) {
                if (r1 == rowTotal) {
                    return 1;
                } else if (r2 == rowTotal) {
                    return -1;
                } else if (param.getComparator() == null) {
                    return 0;
                } else {
                    return param.getComparator().compare(r1, r2);
                }
            }
        };
        FXCollections.sort(table.getItems(), comparator);
        return true;
    }
});

工作示例

如果您仍然有疑问,请找一个工作示例,其方案与您的类似,我创建了一个扩展ExtraPerson的类Person,并创建了ExtraPerson的新对象作为页脚

import java.util.Comparator;

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;

public class TableViewSampleWithoutEdit extends Application {

    private TableView<Person> table = new TableView<Person>();
    private ExtraPerson extraPerson = new ExtraPerson("Ninja Village");

    private final ObservableList<Person> data = FXCollections
            .observableArrayList(
                    new Person("Jacob", "Smith", "jacob.smith@example.com"),
                    new Person("Isabella", "Johnson",
                            "isabella.johnson@example.com"),
                    new Person("Ethan", "Williams",
                            "ethan.williams@example.com"),
                    new Person("Emma", "Jones", "emma.jones@example.com"),
                    new Person("Michael", "Brown", "michael.brown@example.com"),
                    extraPerson);

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

    @Override
    public void start(Stage stage) {
        Scene scene = new Scene(new Group());
        stage.setTitle("Table View Sample");
        stage.setWidth(450);
        stage.setHeight(500);

        final Label label = new Label("Address Book");
        label.setFont(new Font("Arial", 20));

        table.setEditable(true);

        TableColumn firstNameCol = new TableColumn("First Name");
        firstNameCol.setMinWidth(100);
        firstNameCol
                .setCellValueFactory(new PropertyValueFactory<Person, String>(
                        "firstName"));

        TableColumn lastNameCol = new TableColumn("Last Name");
        lastNameCol.setMinWidth(100);
        lastNameCol
                .setCellValueFactory(new PropertyValueFactory<Person, String>(
                        "lastName"));

        TableColumn emailCol = new TableColumn("Email");
        emailCol.setMinWidth(200);
        emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>(
                "email"));

        /**
         * Adding comparator to extraPerson
         */

        table.sortPolicyProperty().set(
                new Callback<TableView<Person>, Boolean>() {

                    @Override
                    public Boolean call(TableView<Person> param) {
                        Comparator<Person> comparator = new Comparator<Person>() {
                            @Override
                            public int compare(Person r1, Person r2) {
                                if (r1 == extraPerson) {
                                    return 1;
                                } else if (r2 == extraPerson) {
                                    return -1;
                                } else if (param.getComparator() == null) {
                                    return 0;
                                } else {
                                    return param.getComparator()
                                            .compare(r1, r2);
                                }
                            }
                        };
                        FXCollections.sort(table.getItems(), comparator);
                        return true;
                    }
                });

        table.setItems(data);
        table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 0, 0, 10));
        vbox.getChildren().addAll(label, table);

        ((Group) scene.getRoot()).getChildren().addAll(vbox);

        stage.setScene(scene);
        stage.show();
    }

    public static class Person {

        private final SimpleStringProperty firstName;
        private final SimpleStringProperty lastName;
        private final SimpleStringProperty email;

        private Person(String fName, String lName, String email) {
            this.firstName = new SimpleStringProperty(fName);
            this.lastName = new SimpleStringProperty(lName);
            this.email = new SimpleStringProperty(email);
        }

        public String getFirstName() {
            return firstName.get();
        }

        public void setFirstName(String fName) {
            firstName.set(fName);
        }

        public String getLastName() {
            return lastName.get();
        }

        public void setLastName(String fName) {
            lastName.set(fName);
        }

        public String getEmail() {
            return email.get();
        }

        public void setEmail(String fName) {
            email.set(fName);
        }
    }

    public static class ExtraPerson extends Person {

        private final SimpleStringProperty address;

        private ExtraPerson(String address) {
            super("Itachi", "Uchiha", "leaf@village.ninja");
            this.address = new SimpleStringProperty(address);
        }

        public String getAddress() {
            return address.get();
        }

        public void setAddress(String address) {
            this.address.set(address);
        }

    }
}

答案 1 :(得分:1)

以下是使用 Java8 lambda表达式中的TreeTableView执行相同操作的代码。

treeTable.sortPolicyProperty().set(treeTableView -> {
    Comparator<? super TreeItem<YOURMODEL>> comparator = (model1, model2) -> {

        if(model1.isTotalRow()) {
            return 1;
        } else if(model2.isTotalRow()) {
            return -1;
        } else if (treeTableView.getComparator() == null) {
            return 0;
        } else {
            return treeTableView.getComparator().compare(model1, model2);
        }
    };

    treeTable.getRoot().getChildren().sort(comparator);

    return true;
});