Jai
Jai

Reputation: 8363

JavaFX Properties: Overriding getBean() method?

Javadoc for ReadOnlyProperty.getBean() says this:

Object getBean()

Returns the Object that contains this property. If this property is not contained in an Object, null is returned.

I noticed that in many Nodes, most (if not all) properties are defined such that getBean() method is overriden. Of course, it makes perfect sense to do this, considering what the description of the getBean() is saying in the Javadoc.

However, most people (like you and me) would probably do this:

ObjectProperty<MyClass> myObj = new SimpleObjectProperty<>();

We do not override the getBean() method, and everything seems to work without it. So, is there something that we are missing out by not overriding getBean()?

I have seen a lot of examples given by the Javadoc that override this method. For example from PseudoClass Javadoc:

public boolean isMagic() {
    return magic.get();
}

public BooleanProperty magicProperty() {
    return magic;
}

public BooleanProperty magic =
    new BooleanPropertyBase(false) {

    @Override protected void invalidated() {
        pseudoClassStateChanged(MAGIC_PSEUDO_CLASS. get());
    }

    @Override public Object getBean() {
        return MyControl.this;
    }

    @Override public String getName() {
        return "magic";
    }
};

private static final PseudoClass MAGIC_PSEUDO_CLASS = PseudoClass.getPseudoClass("xyzzy");

Most of us wouldn't even instantiate a property using the abstract base class (and most likely not even familiar with doing so). Why would the example do it this way, instead of simply doing this:

public boolean isMagic() {
    return magic.get();
}

public BooleanProperty magicProperty() {
    return magic;
}

public BooleanProperty magic =
    new SimpleBooleanPropertyBase(false) {

    @Override protected void invalidated() {
        super.invalidated();
        pseudoClassStateChanged(MAGIC_PSEUDO_CLASS. get());
    }
};

private static final PseudoClass MAGIC_PSEUDO_CLASS = PseudoClass.getPseudoClass("xyzzy");

Or a more familiar way that adds an invalidation listener to the BooleanProperty:

public BooleanProperty magic = new BooleanPropertyBase(false);
magic.addListener(observable -> pseudoClassStateChanged(MAGIC_PSEUDO_CLASS. magic.get());

The way the Javadoc is written, it is suggesting that this is the correct way to do it; if you deviate from this practice, you may not be doing it correctly, and you may not get the desired results.

So, these are my questions:

  1. Do we need to override getBean()?
  2. Under what condition do we need to, or should, override it?
  3. Is there any condition that we must NOT override it?

Upvotes: 2

Views: 557

Answers (1)

Michael Heinrichs
Michael Heinrichs

Reputation: 86

tl;dr

  1. You do not have to override getBean().
  2. You should override it, if you need the information.
  3. I am not aware of any condition, where you must not override it.

The attribute "bean" is meta-information about a property and is optional. (The same applies to the "name" of a property btw.) The core functionality of a property (getting and setting a value, bindings, listeners) will work wether you have specified the name and the owning bean or not.

But you may want to use this information in your application code. For example if you reuse listeners, you can use this information to identify the source of an event. Also generic libraries and tools may use this information. For instance ScenicView could be built using bean and name (though I do not know how it is really implemented).

It is not necessary to override the abstract base class. All SimpleProperty classes have constructors that allow you to set the name and the bean.

The reason most internal properties override the abstract base class instead of instantiating a SimpleProperty is smaller memory footprint. If you have just a couple of properties in a handful of objects, it does not really matter, because you save only a few bytes. But if you have dozens of properties in hundreds or even thousands of nodes and you try to run on a limited device, things like this do start to matter. For the same reason do internal properties override invalidated() instead of attaching a listener.

Upvotes: 5

Related Questions