JavaFX ListView CellFactory禁用项目选择

JavaFX ListView CellFactory禁用项目选择,java,listview,javafx,Java,Listview,Javafx,我有一个带有几个值的类(ListItem),我想显示这些项的列表(ListView)ListItem有一个value属性,我希望ListView显示为它的文本,否则列表的外观和功能应该正常,特别是在项目选择方面。我有以下代码来实现这一点。出于懒惰,FXML被省略了,它只是一个 //FXML的控制器 公共类主控制器{ //包含多个值的包装类 私有类列表项{ 私有字符串值; 公共列表项(字符串值){ 这个值=值; } 公共字符串getValue(){ 返回值; } …//其他有用的东西 } @FXM

我有一个带有几个值的类(
ListItem
),我想显示这些项的列表(
ListView
ListItem
有一个
value
属性,我希望
ListView
显示为它的文本,否则列表的外观和功能应该正常,特别是在项目选择方面。我有以下代码来实现这一点。出于懒惰,FXML被省略了,它只是一个

//FXML的控制器
公共类主控制器{
//包含多个值的包装类
私有类列表项{
私有字符串值;
公共列表项(字符串值){
这个值=值;
}
公共字符串getValue(){
返回值;
}
…//其他有用的东西
}
@FXML私有列表视图列表;
@FXML
公共无效初始化(){
//将列表设置为使用给定的CellFactory显示
list.setCellFactory((列表)->{
返回新的ListCell(){
@凌驾
受保护的void updateItem(ListItem项,布尔值为空){
如果(空)返回;
//显示项的值属性
setText(item.getValue());
}
};
});
//添加测试数据
list.getItems().add(新的ListItem(“测试”));
list.getItems().add(新的ListItem(“test2”));
//选择更改时打印
list.getSelectionModel().SelectEditeProperty().addListener((evt)->{
System.out.println(“选择已更改!”);
});
}
}
这将使用
列表视图
的每个项中的
属性正确显示
列表项
。但是,它会打断选择,并且不会执行
System.out.println(…)
(该项也不会在GUI中突出显示)。我发现删除
list.setCellFactory(…)
语句是罪魁祸首,但这让我陷入了困境

当存在
list.setCellFactory(…)
时,该项使用正确的文本,但无法选择。当缺少
list.setCellFactory(…)
时,该项使用了错误的文本,但可以选择。为了正确显示文本并选择项目,我还需要做其他特殊的事情吗

我已经在谷歌上做了必要的搜索,但是我找不到其他有这个问题的人。非常感谢您的帮助。

您需要添加

super.updateItem(item, empty);
作为
updateItem(…)
的第一行。此调用必须始终存在于被重写的
单元格.updateItem(…)
方法中(对于其他
updatexx
方法,如
updateIndex(…)
),也是如此)

此外,还应确保
updateItem(…)
方法正确处理所有情况,包括单元格为空的情况:

protected void updateItem(ListItem item, boolean empty) {
    super.updateItem(item, empty);
    if (empty) {
        setText(null);
    } else {
        // Display item's value property
        setText(item.getValue());
    }
}

除了James_D的答案之外,在删除项目时撤销对单元格所做的任何更改也是一个好主意。否则,您会遇到如下问题:。将空单元格的
文本设置为
null
。完美。这正是问题所在。我更熟悉C#,把它想象成一个lambda,所以我没有想到要称它为超级类。感谢您对
空的
案例的帮助和建议。
protected void updateItem(ListItem item, boolean empty) {
    super.updateItem(item, empty);
    if (empty) {
        setText(null);
    } else {
        // Display item's value property
        setText(item.getValue());
    }
}