Sun Java Solaris Communities My SDN Account

Article

Stylin' with JavaFX

 
By James L. Weaver, July 2010  

Using JavaFX CSS to Apply Styling to the User Interface

JavaFX is a platform and language for creating Rich Internet Applications (RIA) that execute on the desktop, in Web browsers, on mobile phones, and on TV. It was introduced in 2007, and version 1.3 was released in April 2010. One of the hallmark features of JavaFX 1.3 is the introduction of JavaFX CSS, which provides the ability to apply styling to any element in the user interface. This article focuses on JavaFX Cascading Style Sheets (CSS), which is primarily the domain of designers but is also important for developers to understand.

One of the strengths of JavaFX is that it enables designers and developers to collaborate on creating applications. JavaFX CSS is a feature of JavaFX that encourages this collaboration. As with traditional Web applications, developers can focus on an application's functionality while designers can apply styles to elements of the user interface. For example, Figure 1 contains a screen capture of some JavaFX UI controls using their default styles in a desktop application.

Figure 1: Various JavaFX UI Controls with Their Default Styles
 

Without changing any JavaFX code, but rather making modifications to the style sheets, the designer can re-style the user interface elements (nodes in JavaFX parlance) of an application. Figure 2 contains screen captures of the same UI controls shown in Figure 1 with different CSS style sheets applied. These screen captures are from the StyleEditor example available on the JavaFX.com site at http://javafx.com/samples/StyleEditor/index.html.

Figure 2: JavaFX UI Controls from Figure 1 with Custom Styles Applied
 

Another benefit of JavaFX CSS is that style sheets can be dynamically assigned to the scene at runtime. This allows the appearance of an application to be profoundly altered based on the display footprint of the device or user choice.

Using JavaFX CSS to Style a Label Control

CSS styles can be applied to any node in the scene graph, including controls, layout managers, shapes, and charts. Figure 3 contains a screen capture of an example program that demonstrates how to apply CSS styling to a Label control.

Figure 3: Screen Capture of the StylingExample Program
 

The label consists of both the JavaFX logo and the "CSS Rocks!" text. As shown in Figure 4, when the user hovers over the label, the color and style of the label's text changes. In addition, the mouse cursor changes to a hand icon.

Figure 4: The StylingExample Program When the User Hovers over the Label
 

Obtaining and Running the StylingExample Program

You can download a NetBeans project that includes the StylingExample program. After expanding it into a directory of your choice, start NetBeans, and select the File -> Open Project menu. The Open Project dialog should appear, from which you can navigate to your chosen directory and open the StylingExample project, as shown in Figure 5.

Note: You can obtain the NetBeans IDE 6.9 for JavaFX 1.3 at the JavaFX.com download site: http://javafx.com/downloads.

Figure 5: Opening the StylingExample Project in NetBeans
 

To run the application, click the Run Project button on the toolbar, or press the F6 key. The Run Project icon has the appearance of the Play button on a DVD player, as shown in Figure 6.

Figure 6: Invoking the StylingExample Program in NetBeans
 

The StylingExample application should appear in a window, as shown previously in Figure 3. Hover over the icon or text in the label, noting that its appearance changes to the screen capture shown in Figure 4.

Understanding the StylingExample Program

To open the source code for this program, expand the Source Packages and stylingexample nodes located in the NetBeans Projects pane. You can then double-click the StylingExample.fx node, as shown in Figure 7.

Figure 7: Viewing the StylingExample.fx Source Code in NetBeans
 

To fully understand how JavaFX CSS styling is being applied to the Label control in this example, we'll walk through the StylingExample.fx source code in Listing 1 as well as the mystyle.css file in Listing 2.

Listing 1: StylingExample.fx
package stylingexample;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.*;

Stage {
  scene: Scene {
    stylesheets: "{__DIR__}mystyle.css"
    width: 220
    height: 140
    content: [
      Label {
        layoutX: 10
        layoutY: 10
        id: "mylabel"
        graphic: ImageView {
          image: Image {
            url: "{__DIR__}javafx-logo-154x64.png"
          }
        }
      }
    ]
  }
}
	

Associating a Style Sheet with the Scene

In Listing 1, the stylesheets variable of the Scene class is assigned the URL of the mystyle.css style sheet. In this example, mystyle.css is located in the same folder as the StylingExample.fx source code.

Note: The stylesheets variable's type is actually a sequence of String, but assigning a String instance to the variable causes it to contain a one-element sequence containing the assigned value.

Assigning an ID to a Node for Reference from a Style Sheet

As you'll see when examining the style sheet, two ways of referring to the label from our style sheet are employed in this example. One of these ways depends upon assigning a value to the id variable of the Label instance, as shown in the following line from Listing 1:

id: "mylabel"
	

The id variable is inherited from the Node class, so it is present in every node in the scene.

While we're looking at the label, notice that the text, textFill, and font instance variables are conspicuously absent from the object literal expression. This is because we're going to use the style sheet to control the text value of the label, as well as its color and font characteristics. Also absent are the graphicHPos, graphicVPos, and graphicTextGap variables that control the placement relationship of the text and graphic in the label. Without JavaFX CSS, the object literal for this example would have been similar to the following code snippet, with the variables just mentioned shown in strikethrough type:

Label {
  layoutX: 10
  layoutY: 10
  text: "CSS Rocks!"
  textFill: Color.web("#e76f00");
  font: Font.font("Arial", FontWeight.BOLD, 36)
  graphicHPos: HPos.CENTER
  graphicVPos: VPos.TOP
  graphicTextGap: 2
  graphic: ImageView {
    image: Image {
      url: "{__DIR__}javafx-logo-154x64.png"
    }
  }
}
	

CSS Rules, Selectors, Properties, and Types

Now that the scene has the mystyle.css style sheet associated with it, and the label has a unique id value, we'll take a look at the mystyle.css style sheet in Listing 2.

Listing 2: mystyle.css
.scene {
  -fx-font: bold 36pt "Arial";
  -my-hover-color: #53829e;
}

.label {
  -fx-text-fill: #e76f00;
}

.label:hover {
  -fx-text-fill: -my-hover-color;
  -fx-font-style: italic;
  -fx-cursor: hand;
}

#mylabel {
  -fx-text: "CSS Rocks!";
  -fx-graphic-hpos: center;
  -fx-graphic-vpos: top;
  -fx-graphic-text-gap: 2px;
}
	

Each of the four blocks in Listing 2 are known as CSS rules, with each rule having a selector and one or more properties. Each property has a type and is assigned a value of that type.

Using the .scene Selector

The .scene selector contains JavaFX CSS properties that will be inherited by the nodes in the scene. Because of the following line from Listing 2, every node in our scene graph that contains text will have a bold, 36-point, Arial font by default:

-fx-font: bold 36pt "Arial";
	

Another use for the .scene selector is to define color names that can be used by nodes in the scene graph. The following line from Listing 2 defines a color that we'll use in a bit when the user hovers over the label:

-my-hover-color: #53829e;
	

This technique is called color lookup in JavaFX CSS parlance. See the "Applying Styles to Scenes" article by Stuart Marks at http://stuartmarks.wordpress.com/2010/06/14/applying-styles-to-scenes/ for more information on using the .scene selector.

Using the .label Selector

Every UI control and layout manager has an associated style class name. This name is used in the CSS file as the selector when the desired result is to apply styling to every instance of a particular type of node. In Listing 2, the .label selector represents all (in this case only one) Label instances in the scene graph. The following line causes the color defined by the hexadecimal value e76f00 to be assigned to the -fx-text-fill property of the label style class:

-fx-text-fill: #e76f00;
	

Note: The naming convention for mapping a JavaFX class name to its corresponding CSS style class name is to separate the compound words with hyphens and convert the letters to all lowercase. Using this convention, Label becomes label and ClipView becomes clip-view. The same convention is used to map JavaFX variable names to CSS property names, with the addition of the -fx- prefix. In our example, the textFill instance variable from the Label class becomes fx-text-fill.

Using the hover Pseudo-Class

JavaFX CSS pseudo-classes represent Boolean values and are used to conditionally apply styles to some selectors. For example, the following lines from Listing 2 cause the label's text to change color, its font to be italicized, and its mouse cursor to look like a hand:

  .label:hover {
    -fx-text-fill: -my-hover-color;
    -fx-font-style: italic;
    -fx-cursor: hand;
  }
	

The hover pseudo-class is available in all selectors, and it reflects the current state of the hover instance variable in the associated nodes. Likewise, the disabled, focused, and pressed pseudo-classes are available in all selectors as well, and they represent their corresponding variables in the Node class.

Using the Node ID Selector

As mentioned previously, each node in the scene graph contains an id variable to which a string value may be assigned. The following code from Listing 2 applies styling to the Label instance whose id variable has a value of mylabel.

#mylabel {
  -fx-text: "CSS Rocks!";
  -fx-graphic-hpos: center;
  -fx-graphic-vpos: top;
  -fx-graphic-text-gap: 2px;
}
	

Specifically, the text variable of the label is assigned the value CSS Rocks!, and the instance variables that control the relative positioning of graphics and text are assigned values as well.

Conclusion

As you have experienced, JavaFX CSS is a powerful feature of JavaFX 1.3 that enables designers to create and update the appearance of an application, independent of the JavaFX source code. This is one of the features of JavaFX and its associated toolset that enables designers and developers to work together effectively when creating applications.

See Also

For more information on JavaFX CSS, see:

 

Rate This Article

 

Discussion

We welcome your participation in our community. Please keep your comments civil and on point. You can optionally provide your email address to be notified of replies—your information is not used for any other purpose. By submitting a comment, you agree to these Terms of Use.

 
 Photo of Jim Weaver
Jim Weaver is an author, speaker, teacher, and developer in rich internet application technologies such as JavaFX, and may be contacted at jim.weaver@javafxpert.com

Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.