2017-07-12 19 views
1

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

这是什么?

+0

为'的toString()'导致堆栈溢出的呼叫。在'call()'方法中,将'itemProperty'替换为'itemProperty.toString()'解决了堆栈溢出并消除了ListView空行中的'null'。 –

+0

向Oracle提交了一个错误:9049978 –

+0

Oracle接受了我的错误报告。这也发生在Java 9. http://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8184320 –

回答

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

+0

我不确定这会起作用,因为'null'的asString应该返回'“空“,不是空字符串。但是'ListCell'没有'空'属性?或者,您应该能够绑定到空检查。 – Itai

+0

'Bindings.when'是一个BooleanBinding –

+0

你最近的代码在每一行显示“item”,无论是否为空。 –

相关问题