How to show a list on table column, with few fields of list items

早过忘川 提交于 2020-01-07 03:34:53

问题


UPDATE: This qustion moved to TableColumn should only show one specific value of a complex data type because it's more specific

I want to populate a table with a complex data type Person containing name, id and a List<Person>. At the moment I get a table with the correct name, id and a third column with the whole information of other Persons but it should only show the name of the Personss. Is there any way that my third column shows only the Person.getName() values?

Keywords, solutions welcome! Thank you very much!

Edit: Code

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

So if I fill the table id and name-colums contain the correct name and the third column (with List<Person>) shows [Person [id1, John, ...]...]]. And now I want to ask if theres a possibility that the third column only displays the id or name without manipulating the data?


回答1:


As an alternative to Uluk's solution, consider setting the cell factory on the column, instead of the cell value factory. The choice between these depends on how you regard the relationship between the column and the model (Person). If you consider the list of names to be the data displayed by the column, then Uluk's solution is the way to go. If you consider the list of Person objects to be the data, which are displayed by their names, then this will be the more intuitive option:

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(", ")));
        }
    }
});

This makes it easy to change the way the list is displayed in that column, e.g.:

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



回答2:


You may define cell value factory with the long expanded version where you control which fields to show:

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


来源:https://stackoverflow.com/questions/31136765/tablecolumn-should-only-show-one-specific-value-of-a-complex-data-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!