>
> Specialized methods will be added to `BooleanProperty`,
> `DoubleProperty`, `FloatProperty`, `IntegerProperty`, and
> `LongProperty`, each with one of the preexisting constant wrappers
> that are already in the framework.
> Some wrappers can be deduplicated (we only ever need two wrapper
> instances for boolean values).


You mean the ones in com.sun.javafx.binding [1]?

I use both constant bindings and inline css to override stylesheets and I
like neither, but I'm not sure that exposing constant binding is the
solution. Like John said, it's specific for css and doesn't make much sense
semantically.

About the order of css origins, there was a relevant discussion on JBS [2].

1) Does it make sense to treat values set in code (which IMHO should
> always be the last word on anything) as less important than values from
> AUTHOR and INLINE styles?  This is specified in the CSS document, but
> not fully enforced.


I think that the specifications chose the wrong order. They say "The
implementation allows designers to style an application by using style
sheets to override property values set from code." and I think this was a
poor and mostly surprising choice. I see that John and Scott agree with
that too. I've seen many StackOverflow questions about this confusion, many
can be found by searching "javafx override css from code". I don't know if
it can be changed, as it's a breaking change. I wonder what the original
writer's thoughts were, and what use case they had in mind. Perhaps they
thought that setting values from the java side is akin to specifying a user
stylesheet to the browser, which takes precedence over the browser's style
sheet, but not over the author's stylesheet.

2) Should bound values (which IMHO fall under "values set from code") be
> able to override AUTHOR and INLINE styles?  Why are they being treated
> differently at all?  Which StyleOrigin level do they fall under?
> "USER"?  A 5th level with higher priority than "INLINE"?
>

I don't see how anything should override bound values since they update on
every change and throw an exception if something tries to set the value of
a bound value.

3) Should properties which hold an AUTHOR or INLINE value reject calls
> to `setValue` (to make it clear they are temporary and that your code is
> probably wrong)?  This currently is not in line with the CSS document.
> Note that this will be slightly annoying for the CSS engine as it may
> not be able to "reset" such values as easily as before (which is
> probably the reason it currently works the way it does, but that's no
> excuse IMHO).


I would wait with the ramifications of setting competing values from
different origins until the question of precedence is answered. Perhaps
emitting warnings is better, though I can see some scenarios in which they
will be annoying.

The way I see the order:
1. Setting from code should always take precedence (including the current
bindings over setter order of course).
2. INLINE origin (via setStyle).
3. Stylesheets according to their StyleOrigin as specified by the
non-javafx css specifications [3]: AUTHOR > USER > USER_AGENT (see below
for INLINE).

2 and 3 are already (more or less) specified in JavaFX's css as far as I
can see. However, 1 is not css, hence I don't think StyleOrigin should be
applicable here even. Even more, 2 isn't really css either, it mimics html
tags and shouldn't count as a css StyleOrigin in my opinion.
Note also that a Stylesheet can set its origin [4], even to INLINE, so it
takes precedence over java property setters and conflicts with 'setStyle'
"real" INLINE. I'm not sure if this is a bug because the javafx css specs
say that "Inline styles are specified via the Node setStyle AP".

So, if I were to able to do anything I wanted, I would have restricted
Stylesheets to the options in 3, remove INLINE from a public perspective
and apply it only behind the scenes to 'setStyle' calls, and stop treating
java settings in the css hierarchy (which means removing the USER
StyleOrigin from them). Obviously that breaks a lot of code, but this
behavior would be my general goal. As for how to represent it, maybe a
constant can be added to StyleOrigin to represent java code settings, but
that's not a real css origin. I guess we could call INLINE and the
hypothetical JAVA constants "pseudo-origins", because they don't apply to
stylesheets, and are only used internally. Or just don't check StyleOrigin
when the value is set from java. There are probably more ways.

I also wonder if StyleOrigin should implement Comparable for the precedence
calculations of stylesheets.

However, it seems like an arbitrary fact that attributes in an FXML
> document are equivalent to calling setters from code. Attributes in
> FXML documents could just as well be their own thing, couldn't they?
>

Another good point. I don't really use FXML, so I can't say what I would
expect. There are several options for this.

[1]
https://github.com/openjdk/jfx/tree/master/modules/javafx.base/src/main/java/com/sun/javafx/binding
[2] https://bugs.openjdk.org/browse/JDK-8317434
[3] https://drafts.csswg.org/css-cascade-4/#cascade
[4]
https://openjfx.io/javadoc/21/javafx.graphics/javafx/css/Stylesheet.html#setOrigin(javafx.css.StyleOrigin)

On Tue, Jan 30, 2024 at 9:24 PM Michael Strauß <michaelstr...@gmail.com>
wrote:

> Hi John,
>
> the rule that values set from code are less specific than values set
> in author and inline styles is probably lifted from the CSS
> specification, which says [0]:
>
> "The UA may choose to honor presentational attributes in an HTML
> source document. If so, these attributes are translated to the
> corresponding CSS rules with specificity equal to 0, and are treated
> as if they were inserted at the start of the author style sheet."
>
> However, it seems like an arbitrary fact that attributes in an FXML
> document are equivalent to calling setters from code. Attributes in
> FXML documents could just as well be their own thing, couldn't they?
>
> Let's assume for a moment that we could change that (which is a
> breaking change), and make a distinction between values that come from
> FXML attributes and values that come from code. This would introduce a
> new StyleOrigin.ATTRIBUTE, which would be the origin for all attribute
> values set by FXMLLoader (or by anyone, this is a public API in
> StyleableProperty after all). However, bindings in FXML documents
> would probably continue to use the USER origin. The CSS system would
> then never change values with USER origin, since they definitely don't
> come from attribute values.
>
> With regards to your idea of only allowing cssProperty.setValue() if
> the current value doesn't come from an AUTHOR or INLINE style: it
> seems like this *will* work some of the time, namely before CSS is
> applied for the first time.
>
>
> [0] https://www.w3.org/TR/CSS22/cascade.html#preshint
>
>
> On Tue, Jan 30, 2024 at 3:22 PM John Hendrikx <john.hendr...@gmail.com>
> wrote:
> >
> > Hi Michael,
> >
> > I think we first need to decide what the correct behavior is for CSS
> > properties, as the "bind" solution IMHO is a bug.
> >
> > The StyleOrigin enum encodes the relative priorities of styles and user
> > set values, but it is incomplete and not fully enforced.  There is
> > (currently) actually a 5th level (next to USER_AGENT, USER, AUTHOR and
> > INLINE) where it checks the binding state (it has no choice, as it will
> > get an exception otherwise, or has to call `unbind` first).  Whether
> > that's a bug or should more formally be accepted as the correct behavior
> > remains to be seen.  Also the AUTHOR and INLINE levels are only best
> > effort, as setting a value in code (USER level) will override AUTHOR and
> > INLINE values **temporarily** until the next CSS pass...
> >
> > So first questions to answer IMHO are:
> >
> > 1) Does it make sense to treat values set in code (which IMHO should
> > always be the last word on anything) as less important than values from
> > AUTHOR and INLINE styles?  This is specified in the CSS document, but
> > not fully enforced.
> >
> > 2) Should bound values (which IMHO fall under "values set from code") be
> > able to override AUTHOR and INLINE styles?  Why are they being treated
> > differently at all?  Which StyleOrigin level do they fall under?
> > "USER"?  A 5th level with higher priority than "INLINE"?
> >
> > 3) Should properties which hold an AUTHOR or INLINE value reject calls
> > to `setValue` (to make it clear they are temporary and that your code is
> > probably wrong)?  This currently is not in line with the CSS document.
> > Note that this will be slightly annoying for the CSS engine as it may
> > not be able to "reset" such values as easily as before (which is
> > probably the reason it currently works the way it does, but that's no
> > excuse IMHO).
> >
> > As for your potential solution, if you introduce a constant binding
> > system (to solve a CSS problem), does that make sense for properties as
> > a whole?  What can be achieved with `bindConstant` that can't be done
> > with `setValue`?  `bindConstant` will become the "setter" that always
> > works (never throws an exception...), but probably at a higher cost than
> > using `setValue`.  Would it not make more sense to only have such
> > methods on the Styleable properties (which can then also signal this by
> > using an even higher precedence StyleOrigin instead of relying on
> > bound/unbound) once there is agreement on the above questions?
> >
> > In other words, I'd look more in the direction of providing users with a
> > better "setter" only for CSS properties, that also uses a different
> > StyleOrigin, and to bring both binding and setting in line with the CSS
> > document's specification (or alternatively, to change that
> > specification).  This means that the normal setter provided next to the
> > property method (ie. setXXX) would have to default to some standard
> > behavior, while a more specific setter provided on the property itself
> > can have an overriding behavior, something like:
> >
> >      setX() -> calls cssProperty.setValue()
> >      cssProperty.setValue() -> sets values if not originated from an
> > AUTHOR or INLINE stylesheet, otherwise throws exception (as if bound)
> >      cssProperty.forceValue() -> sets value unconditionally, setting
> > StyleOrigin to some new to introduce 5th level
> > (StyleOrigin.FORCED/DEVELOPER/DEBUG/CONSTANT/FINAL)
> >
> > Binding can then either be categorized as the StyleOrigin.FORCED or if
> > it is StyleOrigin.USER, the CSS engine is free to **unbind** if the need
> > arises.
> >
> > --John
>

Reply via email to