Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding to value of ObservableMap by key

Does JavaFX have a binding type where i supply an observable map with a key and the computed value will always update as the key/value pair changes? Removing that key the key from the map will result to a null value, adding it back will track that value back.

I've been looking around the JavaDoc and found MapProperty, MapBinding and ObservableMapValue, but nothing seems to serve this purpose.

I've already designed my own variant, but would like to use a rather failsafe and tested version.

like image 862
Mordechai Avatar asked Jan 21 '26 05:01

Mordechai


1 Answers

You can just do

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

or, as @VGR points out in the comments

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

Here is a SSCCE using the second approach:

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);
    }
}
like image 193
James_D Avatar answered Jan 23 '26 19:01

James_D



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!