如何定义 ListView 应该使用哪个属性来呈现

JJ *_*man 5 java listview javafx

我有一个 java bean 对象列表,我想在 ListView 控件中显示它。默认情况下,ListView 使用 toString 方法。

如何定义用于在 ListView 中呈现的属性?

我想实现与 TableView 中相同的功能,可以通过以下代码中的 PropertyValueFactory 实现:

@FXML
private TableView<Person> mainTableView;
//...
TableColumn<Person,String> personColumn = new TableColumn<>("Name");List
personColumn.setCellValueFactory(new PropertyValueFactory("name"));
mainTableView.getColumns().add(personColumn);
Run Code Online (Sandbox Code Playgroud)

编辑

看起来没有简单的(开箱即用的)解决方案。基于 James_D 的代码,我创建了泛型类来处理这个问题。它包装了 PropertyValueFactory - 请注意,PropertyValueFactory 首先寻找方法 [NAME]Property() 试图获得可观察性,只有在找不到时才尝试访问标准 bean 属性。

public class PropertyValueFactoryWrapperCellFactory<T> implements Callback<ListView<T>, ListCell<T>> {

    private final PropertyValueFactory<T, String> pvf;

    public PropertyValueFactoryWrapperCellFactory(String propertyName) {
        super();
        pvf = new PropertyValueFactory(propertyName);
    }

    @Override
    public ListCell<T> call(ListView<T> param) {
        return new ListCell<T>() {
            @Override
            public void updateItem(T item, boolean empty) {
                super.updateItem(item, empty);
                textProperty().unbind();
                if (item == null) {
                    return;
                }
                TableColumn.CellDataFeatures<T, String> cdf = new TableColumn.CellDataFeatures<>(null, null, item);
                textProperty().bind(pvf.call(cdf));
            }
        };
    }

}
Run Code Online (Sandbox Code Playgroud)

用法:

@FXML
private ListView<Person> mainListView;
//...
mainListView.setCellFactory(new PropertyValueFactoryWrapperCellFactory("name"));
Run Code Online (Sandbox Code Playgroud)

Jam*_*s_D 6

使用细胞工厂。

如果属性是不可变的,则非常简单:

ListView<MyDataType> listView = new ListView<>();
listView.setCellFactory(new Callback<ListView<MyDataType>, ListCell<MyDataType>>() {
    @Override
    public ListCell<MyDataType> call(ListView<MyDataType> lv) {
        return new ListCell<MyDataType>() {
            @Override
            public void updateItem(MyDataType item, boolean empty) {
                super.updateItem(item, empty);
                if (item == null) {
                    setText(null);
                } else {
                    // assume MyDataType.getSomeProperty() returns a string
                    setText(item.getSomeProperty());
                }
            }
        };
    }
});
Run Code Online (Sandbox Code Playgroud)

如果该属性可以更改其值并且列表视图需要动态更新以响应这些更改,则需要绑定textProperty列表单元格的 :

listView.setCellFactory(new Callback<ListView<MyDataType>, ListCell<MyDataType>>() {
    @Override
    public ListCell<MyDataType> call(ListView<MyDataType> lv) {
        return new ListCell<MyDataType>() {
            @Override
            public void updateItem(MyDataType item, boolean empty) {
                super.updateItem(item, empty);
                textProperty().unbind();
                if (item != null) {
                    // assumes MyDataType.someProperty() returns a StringProperty:
                    textProperty.bind(item.someProperty());
                }
            }
        };
    }
});
Run Code Online (Sandbox Code Playgroud)