组合框值不为';列表中的t在Java11中显示为空

组合框值不为';列表中的t在Java11中显示为空,java,javafx,Java,Javafx,我正在将一个项目从Java8迁移到Java11。当显示不在列表中的值时,ComboBox的行为似乎发生了变化 在Java8中,按下按钮时会显示“CHERRY” 在Java11中,它是空白的,在Windows和Redhat8.2上也是Java14 我一直在调试底层皮肤代码,我找到了一些参考资料,建议它应该可以工作 在javafx.scene.control.skin.ComboBoxListViewSkin.updateDisplayNode()中 是否有任何已知的解决方法 SSCCE 导入j

我正在将一个项目从Java8迁移到Java11。当显示不在列表中的值时,ComboBox的行为似乎发生了变化

  • 在Java8中,按下按钮时会显示“CHERRY”
  • 在Java11中,它是空白的,在Windows和Redhat8.2上也是Java14
我一直在调试底层皮肤代码,我找到了一些参考资料,建议它应该可以工作 在
javafx.scene.control.skin.ComboBoxListViewSkin.updateDisplayNode()中

是否有任何已知的解决方法

SSCCE

导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.ComboBox;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类ComboBoxIssue扩展了应用程序{
公众水果{
苹果、香蕉、樱桃
}
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
public void start(Stage primaryStage)引发异常{
ComboBox水果=新ComboBox();
水果.getItems().addAll(水果.苹果,水果.香蕉);
水果。设定值(水果。苹果);
按钮按钮=新按钮(“更改”);
按钮。设置操作(事件->{
水果。设定值(水果。樱桃);
});
设置场景(新场景(新VBox(水果,按钮));
primaryStage.show();
}
}

此问题已报告为,尚未修复。重复问题存在一个解决方法:

根本原因是
javafx.scene.control.skin.ComboBoxListViewSkin.updateDisplayText(ListCell,T,boolean)
中的代码直接修改控件的文本

String s = item == null && promptText != null ? promptText :
                   c == null ? (item == null ? null : item.toString()) : c.toString(item);
cell.setText(s);
但是,单元格的项(javafx.scene.control.cell.item)仍然为空

javafx.scene.control.Cell
中的Java 8和11之间添加的新代码在更新单元格后进行额外的布局传递,通过重新写入空项使其空白,然后清除文本

/** {@inheritDoc} */
@Override protected void layoutChildren() {
    if (itemDirty) {
        updateItem(getItem(), isEmpty());
        itemDirty = false;
    }
    super.layoutChildren();
}

关于组合选择和在listView和displayNode中同步其选择状态有几个相互交织的问题(注意:添加引用;)我并不想轻率,但最可靠的解决方案不是禁止将值设置为项目列表中不存在的值吗?有没有其他方法的有效用例?@VGR如果JavaFX8支持这一点,那么我会说是:)@VGR否,在SelectionModel层次结构的顶部指定一个未包含的项作为selectedItem,并将combo.value指定为与模型的selectedItem相同:)最可靠的解决方案是清理combo皮肤中的混乱。
String s = item == null && promptText != null ? promptText :
                   c == null ? (item == null ? null : item.toString()) : c.toString(item);
cell.setText(s);
/** {@inheritDoc} */
@Override protected void layoutChildren() {
    if (itemDirty) {
        updateItem(getItem(), isEmpty());
        itemDirty = false;
    }
    super.layoutChildren();
}