Listview 将上下文菜单添加到列表视图<;文件>;结果在空行中显示null

Listview 将上下文菜单添加到列表视图<;文件>;结果在空行中显示null,listview,javafx,contextmenu,Listview,Javafx,Contextmenu,我正在使用CellFactory向ListView添加一个ContextMenu,如图所示。我使用的是ListView而不是ListView。问题是ListView中的空行显示“null”。这是由线路引起的 cell.textProperty().bind(cell.itemProperty().asString()) 但我不能忽略这一点,否则即使行不是空的,所有行都是空的 当行为空时,绑定cell.textProperty()以不显示null的正确方法是什么 public class File

我正在使用CellFactory向ListView添加一个ContextMenu,如图所示。我使用的是
ListView
而不是
ListView
。问题是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();
    }
}

怎么回事?

你可以试试这样的东西:

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

我不确定这是否有效,因为
null
asString
应该返回
“null”
,而不是空字符串。但是
ListCell
没有
empty
属性吗?或者,您应该能够绑定到空检查。
Bindings。当
是BooleanBindings时,您最新的代码在每一行中显示“item”,无论是否为空。@Deanschuze I fixed,现在它应该可以像上面在gif中显示的那样工作。调用
toString()
会导致堆栈溢出。在
call()
方法中,将
itemProperty
替换为
itemProperty。toString()
解决堆栈溢出问题,并消除ListView中空行中的
null
。向Oracle提交错误:9049978Oracle接受我的错误报告。这在Java9中也会发生。
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);