我正在使用CellFactory将ContextMenu添加到ListView,如here所示。我正在使用ListView<File>
而不是ListView<String>
。问题是ListView中的空行显示“null”。这是由线将ContextMenu添加到ListView <File>会导致显示为空的空行
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);
这是什么?
为'的toString()'导致堆栈溢出的呼叫。在'call()'方法中,将'itemProperty'替换为'itemProperty.toString()'解决了堆栈溢出并消除了ListView空行中的'null'。 –
向Oracle提交了一个错误:9049978 –
Oracle接受了我的错误报告。这也发生在Java 9. http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8184320 –