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

JavaFx-在TableView中显示包含观察列表的对象

雍飞雨
2023-03-14

我有一个classPerson,它在其他属性中包含一个可观察列表

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

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


共有1个答案

瞿宏儒
2023-03-14

最简单的方法是创建一个新的CarOfPerson类,其中包含一辆车和车主:

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

现在的主要挑战是:

>

  • 从所有人员中创建一个CarOfPerson列表,但缺点是这需要构建一个潜在的巨大独立实例列表,如果进行任何更改,很难与人员列表保持同步。
  • 创建可观察列表类型的视图,该视图根据需要动态创建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;
        } 
    };
    

    这将成为一个潜在的巨大的可观察人物名单。但是,这些实例中的每一个都将仅在需要时生成,并且如果在当前表中显示。。。。

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

    当然,我的实现效率很低,会遍历所有人,直到找到合适的索引,但这是可以优化的。这是一个暗示。

  •  类似资料:
    • 我正在用一个库编程,我不知道代码,只知道方法,我不能修改它。我试着制作一个“航班”的表格视图,但我不知道如何为每个航班命名(或ID)。有人能帮我吗?谢谢此处有一些代码:

    • 我正在尝试用来自可观察列表的数据填充TableView。我以前做过这个,但由于某种原因我现在无法让它工作。我没有得到任何异常或任何东西,但它根本不会向表添加任何东西。 这个问题很相似,但我发现了JPA引起的另一个问题,这使得提到的的构造函数永远不会执行。相反,JPA会神奇地分配值。 这是我的代码-我剪下了与问题无关的代码: FXML 主要的Java语言 修改Java语言 任何帮助解决这个问题将不胜

    • 我试图从数据(ObservableList)中填充tableview2(fx:id tableview)行。但当它完成时,tableview2只显示空记录。在控制台中,我看到数据中的所有行(ObservableList)。我知道stackoverflow中有很多关于这方面的问题,很抱歉(还有我的英语),但请你问我代码中的错误在哪里?感谢您的帮助或关注)。 更新(添加MainPayer.java和更

    • 我编写的应用程序使用表示和编辑数据列表。 我有数据模型。类似于 如何用包装每个列表项,或者最佳方法是什么?

    • 我刚启动JavaFx,有点拘泥于TableView,它显示了每个列的非常长的字符串表示,如: 而我预计细胞中只会出现“大”、“5000”、“3000”。 这是我的模型: fxml: 最后是控制器: 看起来控制器很好,它能够从数据库中获取值并向TableView添加行,但为什么TableView显示属性对象的字符串表示,而不仅仅是显示值? 非常感谢!