2017-06-16 13 views
0

MyCustomDataオブジェクトを保持するFXMLファイルにListViewを定義しました。私は私のコントローラに次のコードを追加することであるMyCustomDataのプロパティを表示するよう指示する方法を見つけ出すことができる唯一の方法:カスタムオブジェクトの使用時にJavaFX ListViewが表示するプロパティを指定する方法はありますか?

myList.setCellFactory(new Callback<ListView<MyCustomData>, ListCell<MyCustomData>>() { 
    @Override 
    public ListCell<MyCustomData> call(ListView<MyCustomData> param) { 
     return new ListCell<MyCustomData>() { 
      @Override 
      protected void updateItem(MyCustomData item, boolean empty) { 
       super.updateItem(item, empty); 
       if(item != null) { 
        setText(item.getMyProperty()); 
       } 
      } 
     }; 
    } 
}); 

確かワンで、この厄介なコードのすべてを置き換えるためにいいだろう表示されるべきプロパティを指定するFXML内のライナー。これは可能ですか?

答えて

1

まず、セルの実装にバグがあります。 updateItem(...)メソッドのすべての可能性を扱う必要があります。実装では、セルが現在項目を表示してから空のセルとして再利用された場合(項目が削除された場合など)、セルはそのテキストを消去しません。

あなたの代わりに匿名の内部クラスで、ラムダ式としてCallbackを実装する場合は、大幅にコードの量を減らすことができます。

myList.setCellFactory(lv -> new ListCell<MyCustomData>() { 
    @Override 
    protected void updateItem(MyCustomData item, boolean empty) { 
     super.updateItem(item, empty); 
     setText(item == null ? null : item.getMyProperty()); 
    } 
}); 

あなたはこのをたくさんやって、そして軽減したい場合

public class ListViewPropertyCellFactory<T> 
    implements Callback<ListView<T>, ListCell<T>> { 

    private final Function<T, String> property ; 

    public ListViewPropertyCellFactory(Function<T, String> property) { 
     this.property = property ; 
    } 

    @Override 
    public ListCell<T> call(ListView<T> listView) { 
     return new ListCell<T>() { 
      @Override 
      protected void updateItem(T item, boolean empty) { 
       super.updateItem(item, boolean); 
       setText(item == null ? null : property.apply(item)); 
      } 
     }; 
    } 
} 

あなたは

で使用できます。コードの量はなおさら、それは一般的な再利用可能なセルファクトリ実装を作成することは難しいことではありませんあなたが Callbackを実装するクラスを作成するには、より機能的なスタイルを好む場合

、あなたは同様に行うことができ

public class ListViewPropertyCellFactory { 

    public static <T> Callback<ListView<T>, ListCell<T>> of(Function<T, String> property) { 
     return lv -> new ListCell<T>() { 
      @Override 
      protected void updateItem(T item, boolean empty) { 
       super.updateItem(item, boolean) ; 
       setText(item == null ? null : property.apply(item)); 
      } 
     }; 
    } 
} 

myList.setCellFactory(ListViewPropertyCellFactory.of(MyCustomData::getMyProperty)); 
関連する問題