将ContextMenu添加到ListView <file>会导致显示空行

时间:2017-07-12 18:29:27

标签: listview javafx contextmenu

我正在使用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);

到底是什么?

1 个答案:

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

enter image description here