Выглядит для меня как ошибка: по какой-то причине displayNode (то есть содержимое buttonCell) не обновляется при установке незаполненного значения, когда выбрано содержащее значение.Простой доступ к displayNode через его общедоступный API-интерфейс на ComboBoxBaseSkin вызывает правильную настройку.
Чтобы увидеть его обновление, добавьте следующие строки в ваш пример и нажмите эту кнопку, когда не отображается значение без ограничения:
Button display = new Button("getDisplayNode");
display.setOnAction(e -> {
((ComboBoxBaseSkin) testCombo.getSkin()).getDisplayNode();
});
Чтобы обойти проблему, мы можем расширить комбо.Скин и принудительное обновление на каждом этапе макета:
public static class MyComboBoxSkin<T> extends ComboBoxListViewSkin<T> {
public MyComboBoxSkin(ComboBox<T> control) {
super(control);
}
@Override
protected void layoutChildren(double x, double y, double w, double h) {
super.layoutChildren(x, y, w, h);
// must be wrapped inside a runlater, either before or after calling super
Platform.runLater(this::getDisplayNode);
}
}
использование:
testCombo = new ComboBox<>(FXCollections.observableArrayList("Option 1", "Option 2", "Option 3")) {
@Override
protected Skin<?> createDefaultSkin() {
return new MyComboBoxSkin<>(this);
}
};
Примечание: реализация скина интенсивно использует несколько логических грязных флагов, которые, по-видимому, разрушительно взаимодействуют вэто конкретный случай (не понимаю, как именно, к сожалению).Задержка доступа с помощью Platform.runlater, кажется, работает.
Обновление
после некоторого дальнейшего копания выглядит как регрессия , представленная lazy-dirty (не моя формулировка, хотя понравится :) исправить. Пользовательская реализация , предоставленная Томом, прекрасно работает.