Aidenhjj
Aidenhjj

Reputation: 1289

Decorate existing class to support javafx properties

I have an existing class, that I want to keep ignorant of javafx. Is there a generally accepted way to decorate or adapt it so that it supports javafx properties?

I want to do something like the following (which is obviously wrong):

public class FooWrapper {
    /**
     * Decorates a Foo instance with javafx stuff
     */
    private final Foo foo;

    public FooWrapper(Foo toWrap) {
        this.foo = toWrap;
    }

    private final StringProperty name = new SimpleStringProperty();

    public final StringProperty nameProperty() {
        return this.foo.getName();//?????
    }

    public final String getName() {
        return this.nameProperty().get();
    }

    public final void setFirstName(final String name) {
        this.nameProperty().set(name);
    }

}

public class Foo {
    /**
     * Basic class I want to keep ignorant of javafx
     */

    private String name = "hello";

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Upvotes: 0

Views: 140

Answers (1)

Slaw
Slaw

Reputation: 45806

Use the classes in the javafx.beans.property.adapter package.

public class Foo {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

public class FooAdapter {

    private final JavaBeanStringProperty name;

    public FooAdapter(Foo foo) {
        try {
            name = JavaBeanStringPropertyBuilder.create().bean(foo).name("name").build();
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException(ex);
        }
    }

    public final void setName(String name) {
        this.name.set(name);
    }

    public final String getName() {
        return name.get();
    }

    public final StringProperty nameProperty() {
        return name;
    }

}

The adapter property, as created above, requires that the underlying object follows the Java Bean convention for properties. However, there are ways to customize what methods to use for getters/setters.

The adapter property will get the value from the underlying object and, if writable, also write to the underlying object when updated. It can also observe the underlying object for changes if it supports PropertyChangeListeners. Note that this functionality is implemented using reflection; if you are using modules you need to add the appropriate exports/opens directives to your module-info (see the javadoc of the various properties, such as JavaBeanStringProperty, for details).

Upvotes: 3

Related Questions