0

我有一个类Person,它在其他属性中包含一个ObservableList<Car>. 现在我想在 a 中显示数据TableView,使其看起来像这样:

First Name | Last Name | Car
-----------+-----------+---------
John       | Doe       | BMW
John       | Doe       | Audi
Walter     | Johnson   | Chrysler

如何让 JavaFX 提取类列表Person并为该列表中的每个项目创建一行?

4

1 回答 1

0

最简单的方法是创建一个新类 CarOfPerson,其中包含 Car 和所有者:

class CarOfPerson {
    Person myOwner;
    Car    myCar;
    public CarOfPerson(Car car, Person person) {
        myOwner = person;
        myCar = car;
    }
    public Person getOwner() { return myOwner; }
    public Car getCar() { return myCar; }
}

此类现在可以用作表格项。因此,如果您使用这些实例创建一个可观察列表,您可以将表设置为:

    TableColumn<CarOfPerson,String> c1 = new TableColumn<CarOfPerson,String>("first");
    c1.setCellValueFactory(p -> p.getValue().getOwner().firstNameProperty());
    table.getColumns().add(c1);

    TableColumn<CarOfPerson,String> c2 = new TableColumn<CarOfPerson,String>("last");
    c2.setCellValueFactory(p -> p.getValue().getOwner().lastNameProperty());
    table.getColumns().add(c2);

    TableColumn<CarOfPerson,String> c3 = new TableColumn<CarOfPerson,String>("car");
    c3.setCellValueFactory(p -> p.getValue().getCar().typeProperty());
    table.getColumns().add(c3);

现在的主要挑战是:

  1. 从所有 Persons 中创建一个 CarOfPerson 列表,但缺点是这需要构建一个可能巨大的单独实例列表,如果进行任何更改,很难与 Persons 列表保持同步。
  2. 创建一个 ObservableList 类型的视图,它可以按需动态创建 CarOfPerson 对象:

    ObservableList<CarOfPerson> list = new ObservableListBase<CarOfPerson>(){
        ObservableList<Person> myPersons = persons;
        boolean observed = false;
    
        @Override
        public CarOfPerson get(int index) {
            System.out.println("get "+index);
            for (Person person : myPersons) {
                if (person.getNumberOfCars() > index) return new CarOfPerson(person.getCar(index), person);
                index -= person.getNumberOfCars();
            }
            return new CarOfPerson(new Car("null"), new Person("N", "N"));
        }
    
        @Override
        public int size() {
            if (!observed) {
                myPersons.addListener((ListChangeListener.Change<? extends TableInVBox.Person> c) -> {
                    beginChange();
                    nextAdd(0, Integer.MAX_VALUE);
                    endChange();
                });
                observed = true;
            }
            int size = 0;
            for (Person person : myPersons) size += person.getNumberOfCars();
            return size;
        } 
    };
    

这将作为可观察的 CarOfPersons 的潜在巨大列表。但是这些实例中的每一个都将仅按需生成,并且如果显示在当前表中......

myPersons 的观察将更新 TableView 以立即显示人员列表中的更改。因此,添加、删除人员或名称将反映在表格中。

在此处输入图像描述

当然,如果我的实现效率很低,则遍历所有 Persons 直到正确的索引,但这可以进行优化。它作为一个提示。

于 2014-11-27T21:53:48.643 回答