Why does the CellFactory add so many null elements in this list? I explicitly set
an observable array with just "a" and "b"
I don't think it's a problem with the bindings ...
Any suggestions?
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);
}
}
Empty cells always have null as their item.
A string format will format null as the literal string "null" (the string containing the four characters n, u, l, and l). Consequently, your binding will display the text "null" in all the empty cells.
Since you have string data in this column, you can just do
cell.textProperty().bind(cell.itemProperty());
which will set the text to the value null instead of the literal string "null" when the cell is empty.
More generally (i.e. for data types that are not String, so you can't use the binding above), you can do something like
cell.textProperty().bind(Bindings.
when(cell.emptyProperty()).
then("").
otherwise(Bindings.format("%s", cell.itemProperty())));
or
cell.textProperty().bind(Bindings.createStringBinding(() -> {
if (cell.isEmpty()) {
return "" ;
} else {
return String.format("%s", cell.getItem());
}
}, cell.itemProperty(), cell.emptyProperty());
or
cell.textProperty().bind(new StringBinding() {
{
bind(cell.textProperty(), cell.emptyProperty());
}
@Override
public String computeValue() {
return cell.isEmpty() ? "" : String.format("%s", cell.getItem()) ;
}
});