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()) ;
}
});