Reputation: 407
In JavaFX a property binding can often be used to accomplish the same objective as a ChangeListener
or InvalidationListener
. Where the property that is affected by the change may need to be set elsewhere, a binding is problematic because a bound property cannot be set (unless binding is bidirectional which has its own set of issues).
With that background I need to know if a property that is bound (e.g. in the skin) can nevertheless be changed by way of CSS in a style file.
I'm working on some controls where I'd like to set the defaults with bindings. If the 'CSS change' is treated the same as setting the value (which won't work) then I'll have to resort to listeners.
Would be grateful for input. Thanks!
Upvotes: 1
Views: 371
Reputation: 46275
Short answer, no.
A StyleableProperty
has a corresponding CssMetaData
. This latter class has the method isSettable(Styleable)
which states (emphasis mine):
Check to see if the corresponding property on the given Node is settable. This method is called before any styles are looked up for the given property. It is abstract so that the code can check if the property is settable without expanding the property. Generally, the property is settable if it is not null or is not bound.
The existence of this method shows that a StyleableProperty
has the possibility of being non-settable due to some arbitrary reason.
When implementing your own StyleableProperty
, and the corresponding CssMetaData
, you have to implement this method. If the StyleableProperty
also implements Property
then this method should check if the Property
is bound and return false
if it is. This is what is done for all internal StyleableProperty
s (that are also a Property
). Also, if you are using StyleablePropertyFactory
the CssMetaData
it creates will check if the StyleableProperty
is an instance of Property
and then check its bound state.
Even if isSettable
returned true this would result in an exception when the CSS engine tries to set the StyleableProperty
. As you mention yourself, a bound Property
cannot be set. And all standard implementations of Property
will throw an exception if you attempt to do so.
With that said, you have to be careful about how the properties are being set. There is a priority assigned to the method used to set the StyleableProperty
. The Javadoc of StyleableProperty
tells you which methods have precedence over the other.
StyleableProperty allows a javafx.beans.property to be styled from CSS.
This interface allows coordination between CSS processing and a javafx.beans.property. The implementation ensure that the priority for setting the value is, in increasing order and assuming equal importance:
- a style from a user agent stylesheet in Application.setUserAgentStylesheet(java.lang.String)
- value set from code, for example calling Node.setOpacity(double)
- a style from an author stylesheet in Scene.getStylesheets() or Parent.getStylesheets()
- a style from Node.setStyle(java.lang.String)
Upvotes: 3