JavaFX TableView排序策略 [英] JavaFX TableView Sort Policy

查看:215
本文介绍了JavaFX TableView排序策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a tableview which has an observable list of custom class objects attached to it (Class type: SalesInvoiceNetSale). The data all displays fine within the table. The last item in the observable list is a totals row (Class type: SalesInvoiceNetSaleTotal which extends the SalesInvoiceNetSale class). I simply wish to make my table not sort the last record within the array if the user tries to sort the table by column. I have found another post pretty much asking how to do the same thing but can't seem to figure this out, I suspect it's my non understanding of Java 8's Lambda Expressions. 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来说很新,似乎无法找到作为排序政策的一个例子......

Am very new to JavaFX and can't seem to find by way of example of a sort policy...

推荐答案

你可以尝试这样的事情,对你的情况来说:

You can try something like this, for your case :

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表达式

Incase you don't understand what is happening here, a snapshot without lambda expression :

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 的新对象设为页脚

If you still have doubts, please find a working example, with a scenario similar to yours, I have created a class ExtraPerson which extends Person and made the new object of ExtraPerson as the footer

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);
        }

    }
}

这篇关于JavaFX TableView排序策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆