将 ContextMenu 添加到 ListView<File> 会导致空行显示 null
Adding a ContextMenu to a ListView<File> results in empty rows showing null
我正在使用 CellFactory 将 ContextMenu 添加到 ListView,如图 所示。我使用 ListView<File>
而不是 ListView<String>
。问题是 ListView 中的空行显示 "null"。这是由
行引起的
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())
替换为以下内容会产生 WhosebugError。
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);
什么鬼?
您可以尝试这样的操作:
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);
我正在使用 CellFactory 将 ContextMenu 添加到 ListView,如图 ListView<File>
而不是 ListView<String>
。问题是 ListView 中的空行显示 "null"。这是由
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())
替换为以下内容会产生 WhosebugError。
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);
什么鬼?
您可以尝试这样的操作:
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);