<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
My reading of this is that the fix for the caching bug, JDK-8245919
[1] via PR #1072 [2], has inadvertently exposed previously hidden
behavior that is at best an undesirable feature and at worst a bug
(I'd call it a bug). It seems quite unexpected to me that overriding
a variable defined in a user agent stylesheet in an AUTHOR
stylesheet would elevate all properties derived from that variable
to AUTHOR stylesheet status.<br>
<br>
Assuming I'm not missing something, we ought to consider fixing
this.<br>
<br>
-- Kevin<br>
<br>
[1] <a class="moz-txt-link-freetext" href="https://bugs.openjdk.org/browse/JDK-8245919">https://bugs.openjdk.org/browse/JDK-8245919</a><br>
[2] <a class="moz-txt-link-freetext" href="https://github.com/openjdk/jfx/pull/1072">https://github.com/openjdk/jfx/pull/1072</a><br>
<br>
<br>
<div class="moz-cite-prefix">On 7/9/2024 11:21 AM, John Hendrikx
wrote:<br>
</div>
<blockquote type="cite" cite="mid:22719829-feea-1556-5d1e-07e3d92b9805@gmail.com">
<p>Hi Andy,<br>
</p>
<p>I'm confused, nowhere do I propose to remove or otherwise make
the CSS reference system implemented by FX unusable.</p>
<p>I'm first trying to ascertain if this would be expected
behavior (it is indeed unspecified, and the default currently
seems to have been chosen for implementation ease, not for user
friendliness).</p>
<p>**IF** we're considering this worth changing, the change would
simply be that when you override a variable (like -fx-base) that
this is done WITHOUT elevating all styles that use it to the
level of an AUTHOR stylesheet (ie. they remain at USER_AGENT
level as they're specified by Modena). This is not a bad view,
because in a sense, we're not really specifying a style, we're
only overriding a variable. The actual style is still specified
in Modena, which is a USER_AGENT level stylesheet.</p>
<p>As for the bug fix, please read up a bit more on what was
fixed, and what this is now exposing. The fix is almost
completely unrelated (it fixed accidental changes to unrelated
controls at the same level (ie. siblings) due to cache sharing
where one has had a programmatic change, and the other didn't).
This was caused by a CSS calculation bug (calculation was
skipped for all styleable properties that already had a setter
change, if they were encountered first by the CSS system). Now
that this isn't the case anymore, set values are overwritten
with CSS styles more aggressively. Normally those however are
only styles that originate from an AUTHOR stylesheet, so this
can be seen as expected by the user (after all, they WROTE that
stylesheet). But because all styles that use a variable are
being promoted to AUTHOR level, this also includes all unseen
styles in Modena if you specify the variable in your AUTHOR
stylesheet.</p>
<p>> Nowhere did we **actualy** override -fx-text-fill " is not
technically correct since this color depends on -fx-base.</p>
<p>That really depends on your view point. Is overriding a
variable the same as defining all styles (in your AUTHOR
stylesheet) that use that variable? If it was a pre-processor,
that created a fully resolved Modena.css, then this would not be
the case. But it is not implemented as such.</p>
<p>> And I would not want to change how it works currently
because this is the only way (short of overwriting the whole
modena.css styleshseet) for an application to effect a
system-wide change like reacting to changes in the user
preferences or the platform theme.</p>
<p>To be clear, I'm not proposing to change that at all.<br>
</p>
<p>--John<br>
</p>
<div class="moz-cite-prefix">On 09/07/2024 20:00, Andy Goryachev
wrote:<br>
</div>
<blockquote type="cite" cite="mid:BL3PR10MB618571959FD6D663EDF2B8D2E5DB2@BL3PR10MB6185.namprd10.prod.outlook.com">
<meta name="Generator" content="Microsoft Word 15 (filtered
medium)">
<style>@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}@font-face
{font-family:"Yu Gothic";
panose-1:2 11 4 0 0 0 0 0 0 0;}@font-face
{font-family:Aptos;
panose-1:2 11 0 4 2 2 2 2 2 4;}@font-face
{font-family:"Iosevka Fixed SS16";
panose-1:2 0 5 9 3 0 0 0 0 4;}@font-face
{font-family:"Times New Roman \(Body CS\)";
panose-1:2 11 6 4 2 2 2 2 2 4;}@font-face
{font-family:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}@font-face
{font-family:"\@Yu Gothic";
panose-1:2 11 4 0 0 0 0 0 0 0;}p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
font-size:10.0pt;
font-family:"Aptos",sans-serif;}a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}span.EmailStyle210
{mso-style-type:personal-reply;
font-family:"Iosevka Fixed SS16";
color:windowtext;}.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;
mso-ligatures:none;}div.WordSection1
{page:WordSection1;}</style>
<div class="WordSection1">
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16"">1) a buggy implementation coupled with lack of
specification creates a certain expectation<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16"">2) bug gets fixed<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16"">3) people complain because the feature now works
as it should?<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16"">I think (and this is my personal opinion, in the
absence of a formal specification) that this works as
expected now. The statement "</span> Nowhere did we
**actualy** override -fx-text-fill<span style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16""> " is not technically correct since this color
depends on -fx-base.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16"">And I would not want to change how it works
currently because this is the only way (short of
overwriting the whole modena.css styleshseet) for an
application to effect a system-wide change like reacting
to changes in the user preferences or the platform theme.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16"">-andy<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Iosevka Fixed
SS16""><o:p> </o:p></span></p>
<div id="mail-editor-reference-message-container">
<div>
<div style="border:none;border-top:solid #B5C4DF
1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From: </span></b><span style="font-size:12.0pt;color:black">John Hendrikx <a class="moz-txt-link-rfc2396E" href="mailto:john.hendrikx@gmail.com" moz-do-not-send="true"><john.hendrikx@gmail.com></a><br>
<b>Date: </b>Tuesday, July 9, 2024 at 10:45<br>
<b>To: </b>Andy Goryachev <a class="moz-txt-link-rfc2396E" href="mailto:andy.goryachev@oracle.com" moz-do-not-send="true"><andy.goryachev@oracle.com></a>,
openjfx-dev <a class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev@openjdk.org" moz-do-not-send="true"><openjfx-dev@openjdk.org></a><br>
<b>Subject: </b>Re: [External] : Re: CSS Lookups
and their origins (possible regression)<o:p></o:p></span></p>
</div>
<p>Well, it is coming as a surprise to many. With the fix
for the CSS caching bug since JavaFX 21, this "normal"
behavior is becoming much more obvious.<o:p></o:p></p>
<p>Let me repeat one more time:<o:p></o:p></p>
<p>If I have a Label, and I manually set its text fill
with a setter to YELLOW. In JavaFX 17, when I now add a
stylesheet that is empty aside from `-fx-base: WHITE`,
the label's text fill stays YELLOW. <o:p></o:p></p>
<p>Now do this in JavaFX 21. As soon as you add the
stylesheet with `-fx-base: WHITE` in it, the set value
to YELLOW is overridden, even though technically this
value for -fx-text-fill is defined by Modena (which
should not be overriding set values). Nowhere did we
**actualy** override -fx-text-fill, yet the CSS
subsystem now sees **all** values defined by Modena that
are somehow linked to -fx-base as defined directly by
the developer...<o:p></o:p></p>
<p>The reason this didn't happen in JavaFX prior to 21 is
because there was a bug where a CSS value was not fully
calculated if the property it encountered was overridden
via a set value. That was a bug however as cache entries
are shared amongst similar styled nodes, and so not
calculating it fully could have effects on other nodes
that shared that cache entry but did NOT have a property
set directly. Now that this bug is fixed, this problem
is odd behavior is popping up where simply specifying
-fx-base in an empty stylesheet is somehow overriding a
programmatically set text fill. Users are confused by
this, as nowhere in their stylesheet do they themselves
override text fill.<o:p></o:p></p>
<p>This entire mechanism is not specified by CSS, but is
unique to FX. The most similar mechanism in CSS (see
Michael's answer) says the priority of a style should
not be changed when it is using a reference.<o:p></o:p></p>
<p>--John<o:p></o:p></p>
<p class="MsoNormal"><span style="font-size:12.0pt">On
09/07/2024 17:43, Andy Goryachev wrote:<br>
<br>
<o:p></o:p></span></p>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal">> all styles used in Modena
that rely on -fx-base directly or indirectly
suddenly have a higher priority<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">I think it works as designed (and
as expected).<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">-andy<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<div id="mail-editor-reference-message-container">
<div>
<div style="border:none;border-top:solid #B5C4DF
1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">John
Hendrikx <a href="mailto:john.hendrikx@gmail.com" moz-do-not-send="true">
<john.hendrikx@gmail.com></a><br>
<b>Date: </b>Tuesday, July 9, 2024 at 08:25<br>
<b>To: </b>Andy Goryachev <a href="mailto:andy.goryachev@oracle.com" moz-do-not-send="true"><andy.goryachev@oracle.com></a>,
openjfx-dev <a href="mailto:openjfx-dev@openjdk.org" moz-do-not-send="true"><openjfx-dev@openjdk.org></a><br>
<b>Subject: </b>[External] : Re: CSS
Lookups and their origins (possible
regression)</span><o:p></o:p></p>
</div>
<p>It's not that you can't use -fx-base, but that
as it is currently that all styles used in
Modena that rely on -fx-base directly or
indirectly suddenly have a higher priority
(above setters) even though you didn't
specifically specify them in your own
stylesheet. All such styles are being elevated
from USER_AGENT to AUTHOR level (which is above
USER level which is used for setters).<o:p></o:p></p>
<p>--John<o:p></o:p></p>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt">On 09/07/2024
17:03, Andy Goryachev wrote:</span><o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<p class="MsoNormal">I've used this feature in
the past to change the colors in all the
controls, so to me this is the expected
behavior.<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">So in your case (if I got
it right), you need to set the direct style
on the label
(.setStyle("-fx-text-fill:yellow")) instead
of setting the text fill programmatically.
Right?<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal">-andy<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<div id="mail-editor-reference-message-container">
<div>
<div style="border:none;border-top:solid
#B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From: </span></b><span style="font-size:12.0pt;color:black">openjfx-dev
<a href="mailto:openjfx-dev-retn@openjdk.org" moz-do-not-send="true">
<openjfx-dev-retn@openjdk.org></a>
on behalf of John Hendrikx <a href="mailto:john.hendrikx@gmail.com" moz-do-not-send="true">
<john.hendrikx@gmail.com></a><br>
<b>Date: </b>Monday, July 8, 2024
at 17:11<br>
<b>To: </b>openjfx-dev <a href="mailto:openjfx-dev@openjdk.org" moz-do-not-send="true"><openjfx-dev@openjdk.org></a><br>
<b>Subject: </b>Re: CSS Lookups and
their origins (possible regression)</span><o:p></o:p></p>
</div>
<p>I realized I worded the TLDR poorly.<o:p></o:p></p>
<p>Let me try again:<o:p></o:p></p>
<p>TLDR; should styles which use
references (like -fx-base used in
Modena) become AUTHOR level styles if
-fx-base is specified in an AUTHOR
stylesheet? The act of simply
specifying -fx-base in your own AUTHOR
stylesheet elevates hundreds of styles
from Modena to AUTHOR level, as if you
specified them directly...<o:p></o:p></p>
<p>--John<o:p></o:p></p>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt">On
09/07/2024 02:07, John Hendrikx
wrote:</span><o:p></o:p></p>
</div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<p>Hi List,<o:p></o:p></p>
<p>TLDR; should a CSS reference like
-fx-base convert all styles that use
this value (or derive from it) become
AUTHOR level styles (higher priority
than setters) ?<o:p></o:p></p>
<p>Long version:<o:p></o:p></p>
<p>In JavaFX 21, I did a fix (see #1072)
to solve a problem where a CSS value
could be reset on an unrelated
control.<o:p></o:p></p>
<p>This happened when the CSS engine
encountered a stylable that is
overridden by the user (with a
setter), and decided NOT to proceed
with the full CSS value calculation
(as it could not override the user
setting if that CSS value had lower
priority). However, not proceeding
with the calculation meant that a
"SKIP" was stored in a shared cache
which was incorrect. This is because
when this "SKIP" is later encountered
for an unrelated control (the cache
entries are shared for controls with
the same styles at the same level),
they could get their values reset
because they were assumed to be
unstyled.<o:p></o:p></p>
<p>However, this fix has exposed what
seems to be a deeper bug or perhaps an
unfortunate default:<o:p></o:p></p>
<p>JavaFX has a special feature where
you can refer to certain other styles
by using a reference (which is
resolved, recursively, to a final
value). This does not seem to be a
CSS standard, but is a feature only FX
has.<o:p></o:p></p>
<p>It works by saying something like:<o:p></o:p></p>
<p> -fx-base: RED;<o:p></o:p></p>
<p>And then using it like this:<o:p></o:p></p>
<p> -fx-text-fill: -fx-base;<o:p></o:p></p>
<p>This feature works accross
stylesheets of different origins, so
an AUTHOR stylesheet can specify
-fx-base, and when a USER_AGENT refers
to -fx-base, the value comes from the
AUTHOR stylesheet.<o:p></o:p></p>
<p>JavaFX then changes the origin of the
style to the highest priority
encountered while resolving the
reference. This means that Modena can
specify "-fx-text-fill: -fx-base", and
when "-fx-base" is then part of the
AUTHOR style sheet, that ALL Modena
styles that use -fx-base will be
considered AUTHOR level styles, as per
this comment:<o:p></o:p></p>
<div>
<div>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:#3F7F5F">// The
origin of this parsed value is
the greatest of</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:#3F7F5F">// any of
the resolved reference. If a
resolved reference</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:#3F7F5F">// comes
from an inline style, for
example, then the value</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:#3F7F5F">//
calculated from the resolved
lookup should have inline</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:#3F7F5F">// as its
origin. Otherwise, an inline
style could be</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:#3F7F5F">// stored in
shared cache.</span><o:p></o:p></p>
</div>
</div>
<p>I feel that this is a really
unfortunate choice. The style after
all was specified by Modena, only its
value came from another (higher
priority) style sheet. I think a more
logical choice would have been to not
change the priority at all, unless a
"-fx-text-fill" is explicitly made
part of the AUTHOR stylesheet.<o:p></o:p></p>
<p>A consequence of this (and which is
much more visible after the fix) is
that creating a Label with a
setTextFill(Color.YELLOW) in its
constructor will only result in a
yellow text fill if the AUTHOR
stylesheet did not override any of the
Modena colors involved in calculating
the Modena -fx-text-fill default.
Overriding -fx-base in any way will
result in the text fill of the label
to be overridden (as the reference
came from an AUTHOR stylesheet, which
trumps a setter which is of a lower
style origin).<o:p></o:p></p>
<p>The comment also alludes to a
potential problem. If an inline style
would specify "-fx-base", but would be
treated as if it came from Modena
(USER_AGENT level), then this value
could get stored in the cache as
everything except INLINE styles can be
cached. However, I feel that the
changing of style origin level was
then probably done to solve a CACHING
problem, instead of what made logical
sense for users. If we agree that a
resolved reference should not change
the style origin level, then this
would need to be addressed, by perhaps
marking such a calculated value as
uncacheable, instead of overloading
the meaning of style origin.<o:p></o:p></p>
<p>I'd like to hear your thoughts, and
also how to proceed. JavaFX versions
before 21 seemingly allowed overriding
reference without much consequence
because if the user overrode the value
manually, the cache entry would be set
to "SKIP". Now that this is no longer
the case, JavaFX more aggressively
overrides user set values if they
happen to use a referenced value. See
code below.<o:p></o:p></p>
<p>--John<o:p></o:p></p>
<div>
<div>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">.root {</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">-fx-base:
#ff0000;</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">}</span><o:p></o:p></p>
<div>
<div>
<p style="margin:0in;background:white"><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">package</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> app;</span><o:p></o:p></p>
<p style="margin:0in;background:white"><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">import</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black">
javafx.application.Application;</span><o:p></o:p></p>
<p style="margin:0in;background:white"><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">import</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black">
javafx.scene.Scene;</span><o:p></o:p></p>
<p style="margin:0in;background:white"><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">import</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black">
javafx.scene.control.Label;</span><o:p></o:p></p>
<p style="margin:0in;background:white"><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">import</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black">
javafx.scene.paint.Color;</span><o:p></o:p></p>
<p style="margin:0in;background:white"><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">import</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black">
javafx.stage.Stage;</span><o:p></o:p></p>
<p style="margin:0in;background:white"><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">public</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> </span><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">class</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> TestApp </span><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">extends</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> Application {</span><o:p></o:p></p>
<p style="margin:0in;background:white"><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">public</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> </span><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">static</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> </span><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">void</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> main(String[]
args) {</span><o:p></o:p></p>
<p style="margin:0in;background:white"><i><span style="font-size:11.0pt;font-family:Consolas;color:black">launch</span></i><span style="font-size:11.0pt;font-family:Consolas;color:black">(args);</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">}</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:#646464">@Override</span><o:p></o:p></p>
<p style="margin:0in;background:white"><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">public</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> </span><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">void</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> start(Stage
primaryStage) {</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">Scene scene =
</span><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">new</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> Scene(</span><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">new</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> MyLabel());</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:#3F7F5F">// See the
difference with/without
-fx-base in the <u>stylesheet</u></span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">scene.getStylesheets().add(TestApp.</span><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">class</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black">.getResource(</span><span style="font-size:11.0pt;font-family:Consolas;color:#2A00FF">"/style.css"</span><span style="font-size:11.0pt;font-family:Consolas;color:black">).toExternalForm());</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">primaryStage.setScene(scene);</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">primaryStage.show();</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">}</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">}</span><o:p></o:p></p>
<p style="margin:0in;background:white"><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">class</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> MyLabel </span><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">extends</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> Label {</span><o:p></o:p></p>
<p style="margin:0in;background:white"><b><span style="font-size:11.0pt;font-family:Consolas;color:#0000A0">public</span></b><span style="font-size:11.0pt;font-family:Consolas;color:black"> MyLabel() {</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">setTextFill(Color.</span><span style="font-size:11.0pt;font-family:Consolas;color:#0000C0">YELLOW</span><span style="font-size:11.0pt;font-family:Consolas;color:black">);</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">setText(</span><span style="font-size:11.0pt;font-family:Consolas;color:#2A00FF">"Hello
world"</span><span style="font-size:11.0pt;font-family:Consolas;color:black">);</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">}</span><o:p></o:p></p>
<p style="margin:0in;background:white"><span style="font-size:11.0pt;font-family:Consolas;color:black">}</span><o:p></o:p></p>
</div>
</div>
</div>
</div>
<p> <o:p></o:p></p>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</blockquote>
</blockquote>
<br>
</body>
</html>