2017-01-30 4 views
0

JavaFXには、キーで観測可能なマップを提供するバインディングタイプがあります。計算された値はキー/値のペアが変更されると常に更新されますか?そのキーをマップから削除すると、nullという値になり、それを元に戻すとその値が戻されます。ObservableMapの値にキーでバインドする

私はJavaDocを見て、MapPropertyMapBindingObservableMapValueを見つけましたが、何もこの目的に役立たないようです。

私はすでに独自のバリアントを設計していますが、フェールセーフでテスト済みのバージョンを使用したいと考えています。

答えて

2

あなたは

someObjectProperty.bind(Bindings.createObjectBinding(
    () -> myObservableMap.get(key), myObservableMap); 

をただやるか、@VGRここでコメント

someObjectProperty.bind(Bindings.valueAt(someObservableMap, key)); 

に指摘するように、第2のアプローチを使用してSSCCEであることができます。

import java.util.Arrays; 

import javafx.application.Application; 
import javafx.beans.binding.Bindings; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableMap; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.geometry.Insets; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.ComboBox; 
import javafx.scene.control.Label; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.GridPane; 
import javafx.stage.Stage; 

public class BindToObservableMap extends Application { 

    private static final String[] keys = {"key1", "key2", "key3"}; 

    @Override 
    public void start(Stage primaryStage) { 
     ObservableMap<String, String> map = FXCollections.observableHashMap(); 
     for (String k : keys) map.put(k, k.replaceAll("key", "value")); 

     GridPane grid = new GridPane(); 
     grid.setHgap(5); 
     grid.setVgap(5); 
     grid.setPadding(new Insets(10)); 
     for (int i = 0 ; i < keys.length; i++) { 
      grid.add(new Label(keys[i]), 0, i); 
      Label boundLabel = new Label(); 
      boundLabel.textProperty().bind(Bindings.valueAt(map, keys[i])); 
      grid.add(boundLabel, 1, i); 
     } 

     ComboBox<String> keyCombo = new ComboBox<>(); 
     keyCombo.getItems().setAll(keys); 
     TextField valueField = new TextField(); 
     Button update = new Button("Update"); 
     EventHandler<ActionEvent> handler = e -> { 
      map.put(keyCombo.getValue(), valueField.getText()); 
      valueField.clear(); 
      keyCombo.requestFocus(); 
     }; 
     valueField.setOnAction(handler); 
     update.setOnAction(handler); 

     grid.addRow(keys.length, keyCombo, valueField); 
     grid.add(update, 0, keys.length + 1); 

     Scene scene = new Scene(grid); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

はありません特定のキーに関連しない変更の値を再計算するために余分なオーバーヘッドが発生しますか?私のソリューションはリスナーを接続し、そのキーが変更された場合にのみ無効化します。 – Mordechai

+0

@MouseEventリストの他の要素が変更された場合にのみ、無効化リスナーに通知します。値が変更されていないため、変更リスナーに通知しません。したがって、あなたの実装(ObservableMapを実装していますか?)は、マップ内のルックアップを保存するので、少し効率的ですが、追加のコード複雑さのトレードオフは価値がない可能性があります。 –

+1

'Bindings.valueAt'はもっと適切でしょうか? – VGR

関連する問題