【问题标题】:How to show a list on table column, with few fields of list items如何在表格列上显示列表,列表项的字段很少
【发布时间】:2015-09-16 12:47:15
【问题描述】:

更新:这个问题移到TableColumn should only show one specific value of a complex data type,因为它更具体

我想用包含nameidList<Person> 的复杂数据类型Person 填充一个表。目前,我得到一个表格,其中包含正确的nameid 和第三列,其中包含其他Persons 的全部信息,但它应该只显示Personss 的名称。 有什么方法可以让我的第三列只显示 Person.getName() 值?

欢迎关键字,解决方案!非常感谢!

编辑:代码

Person.class

public class Person {
    String id;
    String name;
    List<Person> friends;

public String getId() {...}
public String getName() {....}
public List<Person> getFriends {...}
}

TableView.class

public TableView<Person> createTable() {
    TableColumn<Person, String> firstCol = new TableColumn<>("ID");
        TableColumn<Person, String> secondCol = new TableColumn<>("Name");
        TableColumn<Person, List<Person> thirdCol = new TableColumn<>("Friends");

        PropertyValueFactory<Person, String> firstColFactory = new PropertyValueFactory<>(
            "id");
        PropertyValueFactory<Person, String> secondColFactory = new PropertyValueFactory<>(
            "name");
        PropertyValueFactory<Person, List<Person>> thirdColFactory = new PropertyValueFactory<>(
            "friends");

    firstCol.setCellValueFactory(firstColFactory);
    secondCol.setCellValueFactory(secondColFactory);
    thirdCol.setCellValueFactory(thirdColFactory);

    myTableView.getColumns().addAll(firstCol, secondCol, thirdCol);
}

因此,如果我填写表格idname-colums 包含正确的名称,并且第三列(带有List&lt;Person&gt;)显示[Person [id1, John, ...]...]]。 现在我想问一下是否有可能第三列只显示idname而不处理数据?

【问题讨论】:

标签: javafx javafx-8 tablecolumn


【解决方案1】:

您可以使用长扩展版本定义单元格值工厂,您可以在其中控制要显示的字段:

thirdColFactory.setCellValueFactory(
  ( TableColumn.CellDataFeatures<Person, String> p ) ->
{
    List<Person> friends = p.getValue().getFriends();
    String val = friends
                 .stream()
                 .map( item -> item.getName() )
                 .reduce( "", ( acc, item ) -> acc + ", " + item );
    return new ReadOnlyStringWrapper( val );
});

【讨论】:

  • 而不是reduce(...),使用collect(Collectors.joining(", ")),这样效率更高(循环中没有字符串连接...)。
  • @Uluk 感谢您的回答。对我不起作用,但基于此 James_D 得到了解决方案。
  • 谁能解释一下为什么我在上面的代码中会出现这个错误:“不兼容的类型:lambda 表达式中的参数类型不兼容”?
【解决方案2】:

作为 Uluk 解决方案的替代方案,请考虑在列上设置单元格工厂,而不是单元格值工厂。这些之间的选择取决于您如何看待列和模型之间的关系(Person)。如果您认为名称列表是列显示的数据,那么 Uluk 的解决方案就是要走的路。如果您将Person 对象列表视为按名称显示的数据,那么这将是更直观的选择:

TableColumn<Person, List<Person> thirdCol = new TableColumn<>("Friends");
PropertyValueFactory<Person, List<Person>> thirdColFactory = new PropertyValueFactory<>("friends");
thirdCol.setCellValueFactory(thirdColFactory);

thirdCol.setCellFactory(col -> new TableCell<Person, List<Person>>() {
    @Override
    public void updateItem(List<Person> friends, boolean empty) {
        super.updateItem(friends, empty);
        if (empty) {
            setText(null);
        } else {
            setText(friends.stream().map(Person::getName)
                .collect(Collectors.joining(", ")));
        }
    }
});

这样可以轻松更改列表在该列中的显示方式,例如:

thirdCol.setCellFactory( col -> {
    ListView<Person> listView = new ListView<>();
    listView.setCellFactory(lv -> new ListCell<Person>() {
        @Override
        public void updateItem(Person person, boolean empty) {
            super.updateItem(person, empty);
            if (empty) {
                setText(null);
            } else {
                setText(person.getName());
            }
        }
    });
    return new TableCell<Person, List<Person>>() {
        @Override
        public void updateItem(List<Person> friends, boolean empty) {
            super.updateItem(friends, empty);
            if (empty) {
                setGraphic(null);
            } else {
                listView.getItems().setAll(friends);
                setGraphic(listView);
            }
        }
    };
});

【讨论】:

  • 非常感谢您提供的解决方案!它对我有用,我会尝试理解这一点;)
猜你喜欢
  • 2021-07-17
  • 1970-01-01
  • 2015-08-11
  • 1970-01-01
  • 2021-02-19
  • 2022-11-07
  • 2012-09-02
  • 2013-07-12
相关资源
最近更新 更多