CellFactoryを使用して、ContextMenuをListViewに追加します(here)。私はListView<String>
の代わりにListView<File>
を使用しています。問題は、ListViewの空の行が "null"を表示することです。これは、ラインListViewにContextMenuを追加する<File>空の行にnullが表示される
cell.textProperty().bind(cell.itemProperty().asString());
によって引き起こされるが、私はそれを離れることができないか、行が空でない場合でも、他のすべての行が空白です。
rowが空のときにnullを表示しないようにcell.textProperty()をバインドする正しい方法は何ですか?
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 –
私のバグ報告を受け入れました。これはJava 9でも発生します。http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8184320 –