当前位置: 首页 > 知识库问答 >
问题:

JavaFX TableView排序策略

海鸣
2023-03-14

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

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

梁丘安晏
2023-03-14

下面是在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;
});
蒋永宁
2023-03-14

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

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

工作示例

如果您仍然有疑问,请找到一个与您的场景类似的工作示例,我创建了一个类,扩展了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);
        }

    }
}
 类似资料:
  • 我创建了一个TableView,其中包含一个复选框列(isSelected)和三个信息列(姓名、姓氏、职务)。我想根据用户信息禁用一些复选框。例如,如果用户名为“Peter”,则Peter旁边的复选框将被禁用。但我不能。以下是我的一些代码: 人JAVA 控制器。JAVA

  • 我正在处理一个Symfony应用程序,我有一个用户实体: 我正在尝试将请求负载反序列化到我的实体,如下所示: 因此,当我尝试使用验证器验证对象时: 验证失败,响应为: 但是,当我移除这行时,一切正常。 我正在使用: Symfony 3.4 JMS/Serializer-Bundle 2.3 我该如何解决这个问题?

  • 考虑这对简单的函数模板。 如果我们使用非const参数调用:

  • 本文向大家介绍PowerShell 排序:排序对象/排序,包括了PowerShell 排序:排序对象/排序的使用技巧和注意事项,需要的朋友参考一下 示例 按升序或降序对枚举进行排序 同义词: 假设: 升序排序是默认设置: 阿龙 阿龙 伯尼 查理· 丹尼 要请求降序排列: 丹尼· 查理 ·伯尼· 亚伦 ·亚伦 您可以使用表达式进行排序。 阿龙 阿龙 丹尼· 伯尼· 查理

  • 展示多条数据时,通常需要对数据按照用户指定的列进行排序。 Yii 使用 yii\data\Sort 对象来代表排序方案的有关信息。 特别地, attributes 指定 属性,数据按照其排序。 一个属性可以就是简单的一个 model attribute, 也可以是结合了多个 model 属性或者 DB 列的复合属性。下面将给出更多细节。 attributeOrders 给出每个属性当前设置的 排序

  • 我们正在使用quartz来调度批处理作业。我们正在尝试使用周末或假日策略来触发工作。看看quartz的实现,使用日历实现周末策略是很容易的,但是对于假日的实现。如果在创建工作之前提前定义了假日,那么在自定义日历中与周末一起处理就很容易了。但是,如果可以动态地创建假日,并且在运行时应用策略,我认为如果我们通过重写getNextTimeAfter方法在CronTrigger中处理这一点会更好。但那不起