jfr
jfr

Reputation: 407

Can a JavaFX property that is bound be modified by CSS?

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

Answers (1)

Slaw
Slaw

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 StyleablePropertys (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:

  1. a style from a user agent stylesheet in Application.setUserAgentStylesheet(java.lang.String)
  2. value set from code, for example calling Node.setOpacity(double)
  3. a style from an author stylesheet in Scene.getStylesheets() or Parent.getStylesheets()
  4. a style from Node.setStyle(java.lang.String)

Upvotes: 3

Related Questions