Fozz
Fozz

Reputation: 167

Retrieve property by name

I'm struggling to create a dynamic view generation utility for javafx. I've a handful of Classes that have ObjectProperty's or StringProperty's I'd like to create a ComboBox for each property and bind directly the combo selected value to the Class property by name if possible. Is there some helper or method in any of the javafx.beans.binding that would allow me to specify an Object and a String name and retrieve the property. Or to just retrieve a list of properties. I have a method now that takes the string and matches it to the property by name but it requires I have a case for each property on the object, which on an object with 20+ properties is a lot of duplicate code.

I guess to specify I'm looking for javafx.bean.property as a return type.

Upvotes: 2

Views: 2155

Answers (2)

Sergey Grinev
Sergey Grinev

Reputation: 34498

You can always use Java Reflection.

Getting a list of properties

for (Method method : Node.class.getMethods()) {
    String name = method.getName();
    if (name.endsWith("Property")) {
        Type returnType = method.getReturnType();
        String propName = name.replace("Property", "");
        System.out.println(propName + " : " + returnType);
    }
}

Here is reflective method for binding and example:

public class ReflectiveBind extends Application {
    /**
     * Reflection call for code like
     * slider1.valueProperty().bindBidirectional(slider2.valueProperty());
     *
     * @param bindee Node which you want to be changed by binding
     * @param propertyName name of the property, e.g. width
     * @param bindTarget Node which you want to be updated by binding
     */
    private static void bind(Object bindee, String propertyName, Object bindTarget) throws Exception {
        // here we get slider1.valueProperty()
        Method methodForBindee = bindee.getClass().getMethod(propertyName + "Property", (Class[]) null);
        Object bindableObj = methodForBindee.invoke(bindee);

        // here we get slider2.valueProperty()
        Method methodForBindTarget = bindTarget.getClass().getMethod(propertyName + "Property", (Class[]) null);
        Object bindTargetObj = methodForBindTarget.invoke(bindTarget);

        // here we call bindBidirectional: slider1.valueProperty().bindBidirectional(slider2.valueProperty())
        Method bindMethod = bindableObj.getClass().getMethod("bindBidirectional", Property.class);
        bindMethod.invoke(bindableObj, bindTargetObj);
    }

    @Override
    public void start(Stage stage) {

        Slider slider1 = new Slider();
        Slider slider2 = new Slider();

        VBox root = new VBox(20);
        root.getChildren().addAll(slider1, slider2);

        stage.setScene(new Scene(root, 200, 100));
        stage.show();

        try {
            //same call as slider1.valueProperty().bindBidirectional(slider2.valueProperty());
            bind(slider1, "value", slider2);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

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

Upvotes: 2

Gus
Gus

Reputation: 6871

Check out apache commons bean utils

http://commons.apache.org/beanutils/

You say you want to...

Get the value of the property: http://commons.apache.org/beanutils/api/org/apache/commons/beanutils/BeanUtils.html#getProperty%28java.lang.Object,%20java.lang.String%29

Get List of Properties: http://commons.apache.org/beanutils/api/org/apache/commons/beanutils/BeanUtils.html#describe%28java.lang.Object%29

Lots of other useful methods there, and for UI work they are particularly convenient since many of them return the string form which is what you want to display.

If you want objects rather than strings use the PropertUtils class instead

Get the value of the property (not as a string) http://commons.apache.org/beanutils/v1.8.3/apidocs/org/apache/commons/beanutils/PropertyUtils.html#getProperty%28java.lang.Object,%20java.lang.String%29

Get list of properties: http://commons.apache.org/beanutils/v1.8.3/apidocs/org/apache/commons/beanutils/PropertyUtils.html#describe%28java.lang.Object%29

Upvotes: 0

Related Questions