不在列表中的 ComboBox 值在 Java 11 中显示为空白

ComboBox value that isn't in the list shows as blank in Java 11

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

我一直在调试底层皮肤代码,我发现了一些表明它应该可以工作的参考资料 在 javafx.scene.control.skin.ComboBoxListViewSkin.updateDisplayNode()

// RT-21336 Show the ComboBox value even though it doesn't
// exist in the ComboBox items list (part two of fix)

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

SSCCE

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ComboBoxIssue extends Application {

    public enum Fruit {
        APPLE, BANANA, CHERRY
    }

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        ComboBox<Fruit> fruits = new ComboBox<>();
        fruits.getItems().addAll(Fruit.APPLE, Fruit.BANANA);
        fruits.setValue(Fruit.APPLE);
        Button button = new Button("Change");
        button.setOnAction(event -> {
            fruits.setValue(Fruit.CHERRY);
        });
        primaryStage.setScene(new Scene(new VBox(fruits, button)));
        primaryStage.show();
    }

}

此问题已被报告为 JDK-8221722 and has not yet been fixed. A workaround exists on the duplicate question:

根本原因是javafx.scene.control.skin.ComboBoxListViewSkin.updateDisplayText(ListCell<T>, 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();
}