4

When I want to change the background colour of my TextArea in JavaFX (with CSS), many people recommend "-fx-control-inner-background". But when I look up the Oracle's CSS reference there's no such a thing as "-fx-control-inner-background"! In fact nowhere, in the Internet I could find a reference on that and yet it works!

My question is where do these people discover this information? Why, for example, isn't -fx-background-color working instead?

Joseph_Marzbani
  • 1,796
  • 4
  • 22
  • 36
  • Unfortunately, no such reference exists, to the best of my knowledge. Note that `-fx-control-inner-background` is not a property, but a "looked-up color" which is defined in the default stylesheet, `modena.css`. The only place I'm aware of from where you can find these is the [source code](https://github.com/openjdk/jfx/blob/master/modules/javafx.controls/src/main/resources/com/sun/javafx/scene/control/skin/modena/modena.css). – James_D Jun 19 '20 at 14:15
  • Also see https://stackoverflow.com/questions/62359337/how-to-change-treeview-color-in-javafx-programmatically-without-using-css/62363136#62363136 – James_D Jun 19 '20 at 14:20
  • Thank you for your comment. At least I can stop looking for a reference and think about some "work around" solutions. – Joseph_Marzbani Jun 19 '20 at 14:40
  • I reference the source code fairly often. After a while, it becomes fairly easy to find what you want in there. – James_D Jun 19 '20 at 14:43
  • The problem is an "un-documented" reference can break at any time and become invalid without prior notice – Joseph_Marzbani Jun 19 '20 at 14:46
  • Understood; however CSS just isn't as inherently robust as Java in general. Last time the default stylesheet was changed, a mechanism was provided to programmatically opt to use the previous version (`Application.setUserAgentStylesheet(Application.STYLESHEET_CASPIAN)`), and I'd assume similar mechanisms will be provided for back-compatibility if a new CSS stylesheet is implemented. Removing the "looked-up colors" in modena should really be considered a non-back-compatible change. Using the above code snippet with `STYLESHEET_MODENA` should be enough to future-proof your code. – James_D Jun 19 '20 at 14:53
  • dear James_D, I guess I've found out something very useful that shifts my understanding of FXML CSS. By the way, it's the answer to my own question as well. check it out below – Joseph_Marzbani Jun 19 '20 at 15:02
  • I'll assemble these comments into an answer – James_D Jun 19 '20 at 15:02

3 Answers3

2

Note that -fx-control-inner-background is not a CSS property, but a "looked-up color" (essentially a CSS variable) that is defined in the default stylesheet, modena.css.

To the best of my knowledge, there's no official documentation that describes the looked-up colors used by modena. The only resource I know for finding these is the source code, which quite carefully documents the purpose and use of these variables.

It is valid to be concerned about back-compatibility when relying on undocumented functionality. I'd make the following arguments, that alleviate this concern to some extent:

  • The design of modena.css makes it quite clear the intention is that the looked-up colors defined in there are intended to be a mechanism for easily theming an application, and as such are written as though they are an API
  • Using these looked-up colors is in widespread use in the JavaFX programming community, and removing them from modena.css in a subsequent version would break a lot of code and be met with substantial opposition from the community. As such, these form a "de-facto API".
  • The call

    setUserAgentStylesheet(Application.STYLESHEET_MODENA);
    

    in the Application subclass will ensure that modena is used as the default stylesheet, so if a new default stylesheet is defined for future JavaFX releases, this code will future-proof your application, under the "de-facto API" assumption in the previous bullet point. (Note this also gives the JavaFX team a way forward to create a new stylesheet without breaking existing code, which I think strengthens the "de-facto API" argument.)

So, on balance, I think relying on the looked-up colors that you can find in the modena.css source code is a safe approach.

James_D
  • 201,275
  • 16
  • 291
  • 322
1

I finally found out something useful that shifts my understanding of FXML CSS.

According to this reference, each node in the scene graph can have substructures. For example in our case, TextArea has a substructure called content. It's this content that we should be looking to change and not the entire textarea. In this case:

.text-area .content { -fx-background-color: red; }

works perfectly for me. In other words, we have a region (called content) drawn on the main node (textarea).

This also shows why many people would get only a, for example, red border when they try to change the background of an textarea to red. It's because that narrow border is the only part beneath the content visible to us.

Hope this helps ...

Joseph_Marzbani
  • 1,796
  • 4
  • 22
  • 36
  • Note that doing this will break some of the functionality defined in modena. By default, the content's background color is set (essentially) to `-fx-control-inner-background`. The color of the text will be automatically chosen based on the value of `-fx-control-inner-background` to contrast with it. So by setting the background color but not changing `-fx-control-inner-background`, you lose that predefined functionality. – James_D Jun 19 '20 at 15:17
  • That's another point I just learnt :) Thank you James_D – Joseph_Marzbani Jun 19 '20 at 15:19
0

Modena

Modena has become the default skin for JavaFX applications.

Default Maven dir

%HOMEPATH% on Windows is: C:\Users\USERNAME

The default maven directory is %HOMEPATH%\.m2\repository And JavaFX can be found under %HOMEPATH%\.m2\repository\org\openjfx

modena.css

Since JavaFX (OpenJFX) became modular the directory and file structure has changed. The most recent JavaFX version (as of this writing 19) has placed the CSS at %HOMEPATH%\.m2\repository\org\openjfx\javafx-controls\19 the CSS file can be found inside the following .jar file: javafx-controls-19-win.jar (platform specific)

I have extracted the whole modena folder and put it on GitHub: https://github.com/Remzi1993/OpenJFX-modena

And for anyone who is only interested in the core modena.css here is a public gist: https://gist.github.com/Remzi1993/23350e22a51d325ed00171c117fb66d4

Official OpenJFX repo

You can also find out by going to their GitHub repo: https://github.com/openjdk/jfx/ and the specific directory: https://github.com/openjdk/jfx/tree/master/modules/javafx.controls/src/main/resources/com/sun/javafx/scene/control/skin (The structure might change in the future). They seem to have officially moved to GitHub (finally) and the most recent documentation is also moved to their website at https://openjfx.io

OpenJFX Docs

https://openjfx.io/openjfx-docs/

JavaFX CSS Reference Guide

https://openjfx.io/javadoc/19/javafx.graphics/javafx/scene/doc-files/cssref.html

Remzi Cavdar
  • 135
  • 1
  • 13