I think we should just try it at this point, since it seems nobody knows
why we only trigger stylesheet loading in those two locations anymore,
and it might be good to find out what happens when it is moved to a
different location to better understand the reasoning.

Regardless, putting stylesheet loading in a static block of Control is
not a smart thing to do, as it makes testing much harder than it needs
to be.

Possible locations it could be moved to that are required before you can
even display a control (and wouldn't interfere with unit testing):

- Application class
- Window
- Platform itself even

--John

On 04/06/2026 17:10, Marius Hanl wrote:
> I just came across this (again).
>
> I was building a minimal ui without Controls (no javafx.controls), so
> just using Panes and CSS.
> When using a CSS variable from modena.css like -fx-text-base-color
> like so:
>
> .pane {
>     -fx-background-color: -fx-text-base-color;
> }
>
> I suddenly got errors:
>
> javafx.scene.CssStyleHelper calculateValue
> WARNUNG: Caught 'java.lang.ClassCastException: class java.lang.String
> cannot be cast to class javafx.scene.paint.Paint (java.lang.String is
> in module java.base of loader 'bootstrap'; javafx.scene.paint.Paint is
> in unnamed module of loader 'app')' while converting value for
> '-fx-background-color' from rule '*.pane' in stylesheet file:/xxx
>
> After a while, I found out that this is because of Control or
> PopupControl will load modena.css - so If I don't have any, the CSS
> and CSS variables are not available yet.
> John provided more information - I think the user agent stylesheet
> should be loaded on Application startup. Before the start(Stage)
> method is called.
>
> Any thoughts?
>
> -- Marius
>
> Am 28.11.2025 um 21:02 schrieb John Hendrikx:
>>
>> I'm seeing something odd in Control.  It tries to initialize the
>> default platform user agent stylesheet in a static initializer.  This
>> makes any subclass of Control hard to test (as a unit) as it will try
>> to initialize the entire JavaFX platform.
>>
>> I see little need for this.  The stylesheet is loaded actually in 3
>> different places:
>>
>> - Control
>> - PopupControl
>> - Application (if calling setUserAgentStylesheet with null)
>>
>> Could we perhaps just defer this loading? Or perhaps load it when
>> another class is created that is required for CSS processing?
>>
>> I could imagine the following options:
>>
>> - Initialize this when Window or Scene class is loaded (required to
>> make use of CSS)
>> - Initialize this somewhere in Application as a default
>> - Instead of initializing the whole platform, set only a flag that
>> says "A Control class was loaded already, so when platform starts,
>> set the stylesheet" (if we're for some reason purposely only doing
>> this when a Control class is loaded...)
>>
>> I have no idea why this is in Control or PopupControl specifically. 
>> If I make an FX application without ever loading Control (using
>> Regions for example), should I be surprised that Modena styles are
>> not working when I put them on my regions? What if I do apply some
>> style (let's say "button"), should I be surprised the behavior
>> changes when I later do create (but not use) a Control as then
>> suddenly Modena styles start applying?
>>
>> Is there some attempt here to prevent loading of the Modena
>> stylesheet when NOT using Controls?
>>
>> The code in question in Control static initializer is this:
>>
>> // Ensures that the default application user agent stylesheet is loaded
>>
>> if(Application.getUserAgentStylesheet() == null) {
>>
>> PlatformImpl.setDefaultPlatformUserAgentStylesheet();
>>
>> }
>>
>> I really see no reason why this code needs to be here specifically. 
>> It in fact looks a bit of a hack.
>>
>> --John
>>

Reply via email to