我正在使用CellFactory将ContextMenu添加到ListView,如图here所示。我使用ListView<File>
代替ListView<String>
。问题是ListView中的空行显示&#34; null&#34;。这是由行
cell.textProperty().bind(cell.itemProperty().asString());
但是我不能将其保留,否则即使行不为空,所有行都是空白的。
绑定cell.textProperty()以便在行为空时不显示null的正确方法是什么?
public class FileUploaderVBox extends VBox {
ListView<File> filesToUpload = new ListView<>();
public FileUploaderVBox(Stage primaryStage) {
setAlignment(Pos.TOP_CENTER);
Label l = new Label("Select Files to Upload");
l.setStyle("-fx-font: 12 arial; -fx-font-weight: bold;");
setMargin(l, new Insets(25,0,20,0));
Separator horizSeparator1 = new Separator();
horizSeparator1.prefWidthProperty().bind(widthProperty());
filesToUpload.setCellFactory(lv -> {
ListCell<File> cell = new ListCell<>();
ContextMenu contextMenu = new ContextMenu();
MenuItem deleteItem = new MenuItem();
deleteItem.textProperty().bind(Bindings.format("Delete \"%s\"", cell.itemProperty()));
deleteItem.setOnAction(event -> filesToUpload.getItems().remove(cell.getItem()));
contextMenu.getItems().addAll(deleteItem);
// cell.textProperty().bind(cell.itemProperty());
cell.textProperty().bind(cell.itemProperty().asString());
cell.emptyProperty().addListener((obs, wasEmpty, isNowEmpty) -> {
if (isNowEmpty) {
cell.setContextMenu(null);
} else {
cell.setContextMenu(contextMenu);
}
});
return cell ;
});
Separator horizSeparator2 = new Separator();
horizSeparator2.prefWidthProperty().bind(widthProperty());
Button chooseFileButton = new Button("Choose File");
chooseFileButton.setOnAction(new EventHandler<ActionEvent> () {
@Override
public void handle(ActionEvent event) {
FileChooser fileChooser = new FileChooser();
File f = fileChooser.showOpenDialog(primaryStage);
if (null != f)
filesToUpload.getItems().add(f);
}
});
getChildren().addAll(l, horizSeparator1, filesToUpload, horizSeparator2, chooseFileButton);
}
public ObservableList<File> getFilesToUpload() {
return filesToUpload.getItems();
}
}
修改
使用以下内容替换cell.textProperty().bind(cell.itemProperty().asString())
会产生StackOverflowError。
ObjectProperty<File> itemProperty = cell.itemProperty();
StringBinding sb = Bindings.createStringBinding(new Callable<String>() {
@Override
public String call() throws Exception {
if (null == itemProperty)
return "";
else
return itemProperty.toString();
}
}, itemProperty);
cell.textProperty().bind(sb);
到底是什么?
答案 0 :(得分:1)
您可以尝试这样的事情:
StringBinding stringBinding = new StringBinding(){
{
super.bind(cell.itemProperty().asString());
}
@Override
protected String computeValue() {
if(cell.itemProperty().getValue()==null){
return "";
}
return cell.itemProperty().getValue().getPath();
}
};
cell.textProperty().bind(stringBinding);