2017-07-12 1 views
1

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

何ですか?

+0

のtoString() 'スタックオーバーフローが発生'への呼び出しを。 'call()'メソッドでは、 'itemProperty'を' itemProperty.toString() 'に置き換えてスタックオーバーフローを解決し、ListViewの空の行で' null'を取り除きます。 –

+0

Oracleにバグを提出しました:9049978 –

+0

私のバグ報告を受け入れました。これは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'は ' null "、空の文字列ではありません。しかし 'ListCell'は' empty'プロパティを持っていませんか?あるいは、ヌルチェックにバインドできる必要があります。 – Itai

+0

'Bindings.when'はBooleanBindingです –

+0

最新のコードは、空であるかどうかに関わらず、すべての行で「item」を表示します。 –

関連する問題