JavaFX Tutorial - JavaFX CSS








JavaFX application support theme through CSS settings.

Theming can transforming an entire application's appearance without changing its functionality.

In JavaFX you have the ability to create, modify, or use existing themes to skin your applications.

Application Theme

The setUserAgentStylesheet(String URL) method accepts a valid URL string representing the JavaFX CSS file.

CSS files are bundled inside a jar application or they can reside on the local file system or a remote web server.

To load the CSS file from the classpath, call getClass().getResource("path/some_file.css").toExternalForm() method. It will find the CSS file and produce a URL String.

The following code loads the sample.css file as the current look and feel.

The sample.css file and Java class are in the same directory, so there is no need for a path in front of the file name.

Application.setUserAgentStylesheet(getClass().getResource("sample.css")
.toExternalForm());

Full source code.

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
//  w w w.  j  a  v  a 2  s .c o  m
public class Main extends Application {
  public static void main(String[] args) {
    Application.launch(args);
    
  }

  @Override
  public void start(Stage primaryStage) {
    Application.setUserAgentStylesheet(getClass().getResource("sample.css")
        .toExternalForm());
    
    
    Group root = new Group();
    Scene scene = new Scene(root, 300, 250);

    primaryStage.setScene(scene);
    primaryStage.show();
  }
}

The setUserAgentStylesheet() method applies styling globally to all scenes owned by an application.





Predefined skins

JavaFX 8 currently contains two style sheets, Caspian and Modena, which serve as default cross-platform look and feel skins.

Because the two style sheets are predefined, you can easily switch between them using the setUserAgentStylesheet() method.

The following code shows how to switch between the Caspian and Modena look and feel style sheets.

// Switch  to JavaFX 2.x's CASPIAN  Look and  Feel. Application.setUserAgentStylesheet(STYLESHEET_CASPIAN);

// Switch  to JavaFX 8's Modena Look and  Feel. 
Application.setUserAgentStylesheet(STYLESHEET_MODENA);

We can extract the CSS files, caspian.css and modena.css from the jfxrt.jar file or view the JavaFX source code, located at http://openjdk.java.net.

When calling setUserAgentStylesheet(null), the default style sheet (Modena) will be automatically loaded and set as the current look and feel.

For JavaFX 2.x, the default style sheet will be Caspian.





Scene theme

By calling the scene.getStylesheets().add() method, we can style a single scene and its child nodes.

We would pass in a URL string that represents a JavaFX CSS file.

The following code calls the setUserAgentStylesheet(null) to load Modena as the look and feel and then sets the scene's additional styling by invoking the getStylesheets().add() method.

Application.setUserAgentStylesheet(null); // defaults to Modena

// apply   custom  look  and  feel to the   scene. 
scene.getStylesheets()
.add(getClass().getResource("my_cool_skin.css")
.toExternalForm());

CSS Style

Similar to the way HTML5 uses CSS style sheets, there are selectors or style classes associated with Node objects on the Scene graph.

All JavaFX Scene graph nodes have a setId(), a getStyleClass().add(), and a setStyle()method, respectively, to apply style that could change the node's background color, border, stroke, and so on.

Selectors locates JavaFX nodes on the Scene graph and then we can style them using CSS style definitions.

The two kinds of selector types are id and class.

An id selector is a unique string name that is set on a scene node.

A class selector is a string name that can be added as a tag to any JavaFX node.

The class selector has no relation to the concepts of Java classes. Class selectors are used to group nodes to style them together with one CSS style definition.

ID Selector

The id selector is a unique string name assigned to a node. When using id selectors, we will invoke the setId(String ID) method on a JavaFX node object to set its id.

For example, to target a Button instance whose id is my-button, you would invoke the setId("my-button") method.

To style the button with an id of my-button, you would create a CSS style definition block declared with an id selector #my-button, as shown here:

#my-button {
    -fx-text-fill: rgba(17, 145,  213);
    -fx-border-color:  rgba(255, 255,  255,  .80);
    -fx-border-radius: 8;
    -fx-padding: 6  6  6  6;
}

This CSS styling block will be applied to a button with the unique id of my-button.

The CSS selector name is prefixed with the # symbol while the id in Java code is not using the # symbol.

class Selectors

When using class type selectors we will invoke the getStyleClass().add(String styleClass) method to add a selector to a node. The method allows us to have multiple style classes for styling a node.

The getStyleClass() method returns an ObservableList and we can add and remove style classes to update its appearance dynamically.

The following code targets buttons whose style classes contain a num-button via the getStyleClass().add("num-button") method.

The following is a CSS style definition block declared with a class selector .num-button:

.num-button  {
    -fx-background-color: white, rgb(189,218,230), white;
    -fx-background-radius: 50%;
    -fx-background-insets: 0, 1, 2;
    -fx-font-family:  "Helvetica";
    -fx-text-fill:  black;
    -fx-font-size:  20px;
}

This CSS styling block will be applied to buttons with a style class num-button.

The CSS selector name is prefixed with a dot ., while the selector in Java code is not using the . symbol.

Selector Patterns

Selectors can have patterns to traverse the Scene graph's hierarchy of nodes from the root node to the child nodes.

We can style child nodes whose parent is of a certain type. The following code shows how to style all buttons who's parent is an HBox.

.hbox  > .button {  -fx-text-fill: black;  }

The selector pattern .hbox > .button styles Button nodes that are descendants of an HBox. The greater-than symbol between the two selectors lets the system know which nodes to style.

Selectors for JavaFX nodes are all lowercase letters, and if a control has more than one word they are separated by hyphens. For instance, a GridPane's class selector would be .grid-pane.

We can also style two different kinds of nodes with a common property. The following code shows how to style all labels and text nodes.

.label,.text {  -fx-font-size: 20px;  }