In addition to writing applications in pure Java, JavaFX also supports a declarative markup format called FXML. Additionally, JavaFX lets you use CSS (cascading style sheets) to define control and component styles. The combination of FXML and CSS allows you to specify your user interface in a declarative and designer-friendly format while keeping your application logic in the Java language.
The following code snippet shows the JFXPoetry application converted to FXML
<StackPane prefHeight="375" prefWidth="500"
xmlns:fx="http://javafx.com/fxml"
fx:controller="steveonjava.Controller">
<children>
<ImageView fx:id="imageView">
<image>
<Image fx:id="image" url="http://farm1.static.flickr.com/…"/>
</image>
</ImageView>
<Text fx:id="text" cache="true" text="
The year's at the spring, …"/>
<Button fx:id="button" text="Play Again" onAction="#replay"/>
</children>
</StackPane>
Notice that the element names match the JavaFX classes and that the attributes align with the properties of those classes. For complex types, you can instead specify them as nested elements, which allows you to create the scene graph hierarchy declaratively and specify complex types such as Images.
The fx namespace is defined in the root element and used to hook up a controller class that has the Java application logic to play the animations and media. The controller code is the same as shown earlier, so we have reduced the code to just the stub methods in the following listing:
public class Controller implements Initializable {
private TranslateTransition translate;
private FadeTransition fade;
private MediaPlayer mediaPlayer;
@FXML private Text text;
@FXML private Image image;
@FXML private ImageView imageView;
@FXML private Button button;
@FXML private void replay(ActionEvent event) {…}
@Override public void initialize(URL url, ResourceBundle rb) {…}
}
The variables annotated with @FXML will get their values injected by the elements in the FXML file with the matching fx:id tags. Any method in the controller can be hooked up as an event handler, which is demonstrated by the replay method that is wired up to the onAction event of the button element in the FXML. Finally, you can override the initialize method to do application setup after all the variables have been initialized, such as setting up the transitions, binding, and media for this poetry example.
The FXML file is complemented by a CSS file that defines the styles for the application elements, as shown in the following listing:
#text {
-fx-font-family: serif;
-fx-font-weight: bold;
-fx-font-size: 30pt;
-fx-fill: goldenrod;
-fx-effect: dropshadow(three-pass-box, black, 3, .5, 0, 0);
}
#button {
-fx-background-color: linear-gradient(darkorange, derive(darkorange, -80%));
-fx-background-radius: 24;
-fx-padding: 12;
-fx-font-size: 16pt;
-fx-font-weight: bold;
-fx-text-fill: white;
}
Note: Notice that the text fill is specified differently for a Text element (which inherits the Shape –fx-fill attribute) vs. a Button (which inherits the Control –fx-text-fill attribute)
JavaFX stylesheets are based on the W3C CSS2.1 specification with some additions inspired from CSS3. In addition, many JavaFX-specific properties are exposed by prefixing the property name with "-fx-", as shown in the above example to set the font size, fill, and drop shadow effect. In addition, the above CSS includes a new styling for the "Play Again" button so it matches the overall theme of the application better.
The final step is to load the FXML and CSS files in the start method of your application, as shown in the following code:
Parent root = FXMLLoader.load( ().getResource("JFXPoetry.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add( ().getResource("JFXPoetry.css").toExternalForm());
Notice that the FXML loader expects a URL, while the stylesheet list on Scene is of type String. To convert a URL to a String for the stylesheet, you can call toExternalForm to get the correct URI syntax for the resource you are loading. Upon running you can see the new CSS button design as shown in Figure 6.
Figure 6: FXML version of JFXPoetry with a CSS-styled button
To try the completed FXML example, complete with animation and audio, click the following url: http://steveonjava.com/refcard/JFXPoetry-FXML.jnlp
For both the Java and FXML versions of this application, you can find the source code on GitHub: https://github.com/steveonjava/JFXPoetry
If you are a JVM language fan, you can also code your application in Scala, Groovy, Visage, or other languages that compile to JVM
{{ parent.title || parent.header.title}}
{{ parent.tldr }}
{{ parent.linkDescription }}
{{ parent.urlSource.name }}