Global Stylesheet for your JavaFX Application

You can style your JavaFX Scene by CSS as you can read here and here.All this examples show how to apply a specific Stylesheet to one Scene by using

myScene.getStylesheets().add("path/to/custom.css");

Inside the SceneGraph of this Scene all Nodes will use the defined Stylesheets. But while your Application grows you will normally have more than one Scene. Each Window in JavaFX holds its own Scene. Even if your Application only uses one Stage you will normally have more than one window while every ContextMenu is Window. So if you use custom ContextMenus or a ChoiceBox inside your application this Components will technically be displayed in a separate Window with a new Scene and SceneGraph. But with the code mentioned above only “myScene” will use the custom Stylesheet. The Scene of the ContextMenu will not be affected by this. One trick here is to set the Stylesheet manually to the Scene of the Window:

myContextMenu.getScene().getStylesheets().add("path/to/custom.css");

But this is only a bad workaround and you won’t do this for every ContextMenu. When you use a ChoiceBox you even can’t access the Scene of the popup because this is defined in private methods of the ChoiceBoxSkin.

But there is a way to set a global Stylesheet to all Scenes. By using the JavaFX 8 class StyleManager you can define the default CSS files. The class uses the singleton pattern and can easily accepted. The following code will add a CSS file to all Stylesheets of all Scenes:

StyleManager.getInstance().addUserAgentStylesheet(AQUA_CSS_NAME);

Currently there is one bug with this. The default Stylesheet (currently caspian) is defined inside the StyleManger, too. But the default will not be set until a first Node is created. When adding a additional user defined Stylesheet a Exception is thrown. So to avoid problems you have to set the default CSS before adding a custom one. This can currently only done by calling a private API:

PlatformImpl.setDefaultPlatformUserAgentStylesheet();
StyleManager.getInstance().addUserAgentStylesheet(AQUA_CSS_NAME);

I will open a issue at http://javafx-jira.kenai.com about this behavior.

addition

With the help of Jonathan Giles (see comments) I found a better way without using private APIs. You can easily set the default stylesheet by using “Application.setUserAgentStylesheet(String url)”. If you use null as parameter value the default stylesheet (currently caspian) will be used. So here is the code without using a private API:

Application.setUserAgentStylesheet(null);
StyleManager.getInstance().addUserAgentStylesheet(AQUA_CSS_NAME);

7 Responses to Global Stylesheet for your JavaFX Application

  1. I don’t think I understand. Even with the latest version of JDK 8 (b87), StyleManager is still private api (com.sun.javafx.css.StyleManager). Is there a way to do this without using the private api?

  2. Please help the above :
    Application.setUserAgentStylesheet(null);

    not working.

    It says setUserAgentStylesheet is not a known method.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>