JavaFX JDK 9.0.4 ListView celFactory 添加空单元格

JavaFX JDK 9.0.4 ListView celFactory adds null cells

为什么 CellFactory 会在此列表中添加这么多空元素?我明确设置 一个只有 "a" 和 "b"
的可观察数组 我不认为这是绑定的问题... 有什么建议么?

package at.kingcastle.misc;

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class MainSpielwiese  extends Application {
    @Override
    public void start(Stage primaryStage) {
        ListView<String> lv = new ListView<>();
        lv.setItems(FXCollections.observableArrayList(new String[] {"a", "b"}));

        StackPane root = new StackPane();
        root.getChildren().add(lv);

        Scene scene = new Scene(root, 300, 250);
        primaryStage.setScene(scene);
        primaryStage.show();

        lv.setCellFactory(list -> {
            ListCell<String> cell = new ListCell<>();
            ContextMenu contextMenu = new ContextMenu();
            cell.textProperty().bind(Bindings.format("%s", cell.itemProperty()));
            return cell;
        });
    }

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

空单元格的 item 总是 null

字符串格式会将 null 格式化为文字字符串 "null"(包含四个字符 null)。因此,您的绑定将在所有空单元格中显示文本 "null"

由于您在此列中有字符串数据,因此您可以这样做

cell.textProperty().bind(cell.itemProperty());

当单元格为空时,这会将文本设置为 null 而不是文字字符串 "null"

更一般地(即对于不是 String 的数据类型,因此您不能使用上面的绑定),您可以执行类似

的操作
cell.textProperty().bind(Bindings.
    when(cell.emptyProperty()).
    then("").
    otherwise(Bindings.format("%s", cell.itemProperty())));

cell.textProperty().bind(Bindings.createStringBinding(() -> {
    if (cell.isEmpty()) {
        return "" ;
    } else {
        return String.format("%s", cell.getItem());
    }
}, cell.itemProperty(), cell.emptyProperty());

cell.textProperty().bind(new StringBinding() {
    {
        bind(cell.textProperty(), cell.emptyProperty());
    }
    @Override
    public String computeValue() {
        return cell.isEmpty() ? "" : String.format("%s", cell.getItem()) ;
    }
});