2016-12-26 7 views
2

短く:Mapの値をの値に変更したことに基づいて、ListViewの内容を更新する方法を探しています。ObservableMapに値の抽出機能がありますか?

状況:

"ソース" LinkedHashMap<String, Data>は、アプリケーションの論理的な側面にあります。

は、GUIの一部であり、リストビューなど:

// Gui list. 
ListView<Data> list = new ListView<>(); 

// Observable map wrapping logical map 
ObservableMap<String, Data> items = FXCollections.observableMap(logic.getLogicalMap()); 
// This listener will cause gui list to also change logical list 
items.addListener((MapChangeListener<String, Data>) change -> 
{ 
    list.getItems().removeAll(change.getValueRemoved()); 
    if (change.wasAdded()) 
    { 
     list.getItems().add(change.getValueAdded()); 
    } 
}); 
// Show values of map in ListView. 
list.getItems().setAll(items.values()); 

list.setCellFactory(new Callback<ListView<Data>, ListCell<Data>>() 
{ 
    @Override 
    public ListCell<Data> call(ListView<Data> list) 
    { 
     return new DataCell(); 
    } 
}); 
// Basically cells that update when map is updated. 
private static class DataCell extends ListCell<Data> 
{ 
    @Override 
    public void updateItem(Data item, boolean empty) 
    { 
     super.updateItem(item, empty); 

     if (item != null) 
     { 
      this.setText(item.toString()); 
     } 
     else 
     { 
      this.setText(""); 
     } 
    } 
} 

今:私はMap#values()に含まれるDataに加えられた変更を表示するために、細胞を望むまで、すべてがクールです。

私はExtractorsに出くわしましたが、明らかにObservableListsのみです。 それでは、ObservableMap(ListViewに通知する)に「携帯」(値)レベルで起こっている更新を通知するにはどうすればよいですか? JavaBeanのようにDataをRefractoring

+0

あなたの 'Data'クラスはどのように見えますか?外部から反応してデータの内部で起こる変化に対応できるようにするには、プロパティや少なくともリスナーを登録する機能のようなものを提供する必要があります。 – Calculator

+0

この質問を投稿して約10分後まではPOJOでした。これが私のDataCell#updateItemが普通のitem.toString()を使用している理由です。 これまではデータも不変だったので、この方法でした。以来、私たちはJavaBeanとみなすことができる "状態の更新"を受け取ることになるので、ここに保持されるすべてのデータはJavaFXのプロパティになります。 注:セルのデータをData beanのプロパティにバインドするオプションを検討中です。データのこの問題の構造を解決するために、私の問題解決に役立つ限り、基本的には「任意」にすることができます。 – Ernio

答えて

1

(POJOあった)と(DataCell#updateItemに)使用して:

this.textProperty().bind(Bindings.concat(item.propertyOne(), "/", item.propertyTwo())); 

は私の問題を解決します。

+0

また、 'updateItem()'メソッドでバインディングを使用する代わりに、 'list.setItems(FXCollections.observableArrayList(d - > new Observable [] {d.propertyOne()、d.propertyTwo ); 'そして、あなたのセルの' updateItem'メソッドで普通の 'setText(...)'を使うだけです。つまり、マップ上に抽出子は必要なく、リスト上に置くだけで十分です。リストにはマップと同じオブジェクトが含まれているため、変更があった場合は正しいプロパティと更新を確認します –

+0

リスナーでは、項目を「マルチセット」のように動作させることに注意してください。その値をマップから削除すると、最初のものがリストから削除されます。さらに、値として 'null'を追加すると、リストに新しいアイテムを追加することでアイテムを削除できます(NPE 'updateItem'にあります)。 – fabian

関連する問題