image
CHAPTER
2
JavaFX Basics
JavaFX is a toolkit specifically used for creating graphical user interfaces, and therefore it includes much more than just a collection of controls. This chapter briefly introduces the various components, APIs, and tools of JavaFX. You’ll need this basic knowledge in later chapters because the control APIs either interface to the other JavaFX APIs or use them internally. Developers who want to create a JavaFX-based application need to know the basics covered in this chapter. However, since you don’t need to know all features in depth to be able to customize the JavaFX controls, this chapter will serve only as an overview of them. To acquire deeper knowledge on any of these topics, consult Quick Start Guide to JavaFX (McGraw-Hill, 2014), JavaFX 8: Introduction by Example (Apress, 2014), or Pro JavaFX 8 (Apress, 2014).
image
NOTE
In the Appendix of this book you will find some more starting points for these topics.
Your First JavaFX Application
Almost every book starts with a “HelloWorld” example when teaching a new programming language or framework. Even though this is not a book for learning JavaFX from the ground up, let’s follow that trend and start with a basic HelloWorld application, shown here:
image
image
When you start the program, a dialog will appear onscreen. Figure 2-1 shows how this dialog looks on Mac OS X. This example is one of the easiest graphical applications that can be created; however, even in its simplicity, this application uses a number of JavaFX APIs. When looking at the import statements of the Java file, for example, you can see that classes from the following three JavaFX packages are loaded for this simple program:
image
image
image
FIGURE 2-1.Your first JavaFX application: HelloWorld
imagejavafx.application
imagejavafx.stage
imagejavafx.scene
In the following sections, I will discuss the classes and APIs used in this program so you can gain a better understanding of how JavaFX is working.
image
NOTE
As mentioned in Chapter 1, JavaFX has been bundled with the JDK and JRE since Java SE 8. Therefore, to compile and run a JavaFX application, no additional software is needed. You can develop the HelloWorld class shown previously with any Java IDE or even with a simple text editor.
JavaFX Application Life Cycle
As you can see in the HelloWorld example program, each JavaFX application needs to extend the javafx.application.Application class, which defines the life cycle of an application. This is covered by the following methods that are called automatically by the JavaFX Framework:
imageApplication.init() can be used to define and prepare everything before the application starts. This method is called in a special thread, the JavaFX launcher thread.
imageApplication.start(Stage stage) is called to start the application. This method should be used to define the complete application and its view by adding a scene that defines the main window of the application. This method is called in the JavaFX application thread. I’ll provide more information about the threading model of JavaFX later in the chapter.
imageApplication.stop() is called once the application is closed. This can happen for different reasons; one example is if a user clicks the exit icon of the main frame. This method is called in the JavaFX application thread.
image  Each of these methods can be overridden in a JavaFX application. In most cases, you need only to define the start(…) method because that’s where you define the complete user interface. In the HelloWorld example, the UI is defined by a button that is wrapped in a StackPane control, and the main method is part of the Application class. You will find this behavior in most JavaFX examples and tutorials. In a large application, you could extract the main method to any other classes that will manage your application, of course. The main(…) method calls the static launch(…) method of the Application class. This method internally starts the JavaFX environment by creating all the needed threads, the life cycle, and so on.
Defining the Main Window by Using the Stage Class
As you can see in the HelloWorld example, the Application.start(Stage stage) method is used to define the UI of the application. The stage parameter of the method is provided by the JavaFX application life cycle, and it defines the main window of the application. The Stage is a wrapper class around a window that is offered by the underlying operating system and is used by JavaFX to render the application onscreen. As in AWT, a peer entity is used in Java to access the native window. (The same technique is used for pop-ups, too.) Figure 2-2 shows a short UML diagram that defines the class hierarchy of all the basic JavaFX Window classes.
image
image
image
FIGURE 2-2.JavaFX Window class hierarchy
As you can see, a stage is a special window. It provides some additional information and methods to define and skin the main window of the JavaFX application. Table 2-1 describes all the properties that are part of a stage.
image
TABLE 2-1.Properties of the Stage Class
All mentioned properties are implemented by using the JavaFX property API, which is used a lot in JavaFX and will be used in most of the examples in this book. Don’t worry if you haven’t heard about the property API until now. All properties of the Stage class have normal getter and setter methods like you know from other JavaBean implementations; however, by using the property API internally, the implementation of these getter and setter methods is different from the one you know from plain old Java objects (POJOs). The API will be shown in more depth later in this chapter.
In addition to the properties of the Stage class, its parent class, Window, defines a set of properties, as described in Table 2-2.
image
image
TABLE 2-2.Properties of the Window Class
In addition to the properties, the Stage class and the Window class contain some useful methods to interact with instances from Java code. Tables 2-3 and 2-4 contain an overview of these methods.
image
TABLE 2-3.Methods of the Stage Class
image
TABLE 2-4.Methods of the Window Class
image
NOTE
The shown methods and properties contain some classes and functionality that weren't described until now. The defined classes like EventHandler are part of the JavaFX framework and will be described later in the book in more detail.
As shown in Table 2-5, the style of a stage can be defined. By using a style, you can simply change the decoration and behavior of a Stage instance. Table 2-5 provides an overview of all supported types.
image
TABLE 2-5.Stage Styles
By setting some of these properties in the Start(…) method of an application, you can specify the look of the main window. Here is an example of a decorated frame:
image
image
Figure 2-3 shows the application running on Mac OS and Windows 7. Now that the application is created and the window is specified, controls can be added to the surface.
image
image
image
FIGURE 2-3.Application on different operating systems
The Scene Graph
Another API used in the HelloWorld application is the scene graph. In JavaFX, each window contains a so-called scene graph, which is an acyclic-directed graph that can be accessed by the Scene class in JavaFX. A scene graph manages all the items that will be rendered on the screen. None of these items can have more than one parent, and each element that is part of the scene graph is called a node. Examples for nodes include a rectangle, a button, or a panel that holds other nodes. Because the scene graph manages all of these nodes in an internal model, it knows which nodes should be displayed at what location onscreen and which components and areas need to be repainted. Each scene graph has a root node that, by default, is a group that holds all the other nodes in any hierarchy. The StackPane control is the root node of the HelloWorld application, and it holds only one node: the Hello World button.
image
image
The actual layout of the buttons is taken from StackPane. Unlike Swing, in which a JPanel class is the default container and different layout managers such as BorderLayout and FlowLayout are used for positioning elements, JavaFX provides different panes that are responsible for grouping and laying out the child nodes.
By using the JavaFX scene graph, developers can use significantly more features than in Swing. The scene graph supports transformations such as scaling or rotation, and you can add and display 3D objects in it. Since the scene graph is the global administrative body of all controls in JavaFX, its structure and API will be described in more detail in Chapter 3. (The application life cycle and the stage API will not be covered further.)
Now that I’ve discussed three of the JavaFX APIs that were used in the HelloWorld application (application, stage, and scene graph), I’ll present the entire structure of JavaFX and its various APIs.
Technical Design of the JavaFX Toolkit
As you already know from many other frameworks, the JavaFX toolkit is composed of different APIs. JavaFX can be roughly divided internally into three layers:
image  Native layer
image  Private layer
image  Public layer
For a better overview, Figure 2-4 shows a graph in which the different layers and their components are shown schematically.
image
image
image
FIGURE 2-4.JavaFX library stack
JavaFX developers should only ever work with the public APIs. As with all other components of the JDK, it is not recommended to use private APIs to program, even with JavaFX. These classes may change at any time, and any Java update can create an incompatibility for your application. For this reason, the components of the native and private layers are presented here only briefly.
The Native Layer
The native part of JavaFX is not written in Java. Instead, these components are native libraries that grant access to the native OS layer. A big part of the native libraries of JavaFX are the Prism implementations. Prism is a technology-independent layer to render the JavaFX views. Because high-performance graphics are one of the most important issues for UI toolkits like JavaFX, there are several operating system or hardware-oriented implementations of Prism. On Windows, this works normally with a Direct3D version, while on other systems, an OpenGL-based implementation of Prism is used. In addition to these implementations, the native layer still contains implementations of the media and web engines. With these implementations, it is possible in a JavaFX application to show media content, such as movies and music, or embed web pages directly in an application. By using native interfaces, JavaFX has achieved very good performance in these areas. As mentioned, the native parts are not developed in Java. This is also the reason why JavaFX can’t simply be delivered as a one-JAR framework: The native components are specific to operating systems and need to be delivered as compiled libraries. Although most parts of JavaFX are open source, a few fonts and the VP6 codec are not, which creates license issues.
image
NOTE
JavaFX has some optional APIs and features. The media support is an example of an optional feature. You can check for the availability of these optional features in code by using the Platform.isSupported(…) method. All optional features are defined by the enumeration javafx.application.ConditionalFeature.
Private API Layer
The private APIs contain internal classes that are part of the JRE. These classes are defined in special packages (com.sun.*). The definition of the Prism API is, for example, part of the private APIs. All these APIs are closed under the com.sun package, and a developer should never use them because these APIs can change in each new Java version.
Public API Layer
The most important part for each developer is the public part of the architecture stack. This part contains all the JavaFX classes that can and should be used when developing an application. Because of this, the next section will introduce all the main public APIs of JavaFX.
JavaFX Public APIs
JavaFX has a lot of different classes packed into its public framework. All of these classes are allocated in different APIs. By taking a look at the package structure of JavaFX (see Table 2-6), you can learn about the core APIs.
image
TABLE 2-6.JavaFX Public Packages
The following sections contain overviews of all the different APIs. Most of them will be covered again later in the book when their interoperability with specific controls is shown. Here, I’ll primarily show some special features of the APIs because developers should know the basic purpose and usage of them to understand all the examples in this book.
Application and Life Cycle
The application API was discussed earlier in reference to the HelloWorld application.
Stage API
All the important classes that are part of javafx.stage.* were discussed when explaining the HelloWorld application.
Scene Graph and Controls
The scene graph API is one of the biggest parts of JavaFX. It contains the definition of the scene graph and all kinds of nodes. To simplify, you can group all the nodes in four categories, as shown here:
image  Simple nodes, such as lines or rectangles
image  Groups and panes, such as the FlowPane
image  Controls, such as buttons and text fields
image  Complex nodes, such as rendered video, images, and web pages
The main focus of this book is on the APIs that are part of the javafx.scene package and its subpackages.
Event Handling
JavaFX offers event handling for different types of input. For this reason, there are different event types in JavaFX, such as MouseEvent, KeyEvent, and TouchEvent. Event handlers can be easily registered for the different input events. The following code snippet shows how to register an event handler to a button that will fire with every touch on the screen:
image
image
The event handlers define how a user can interact with a JavaFX application. Mostly, the event handlers are registered to single controls like a Button instance. When covering different controls later in this book, I’ll explain the specific event types that are supported by these controls in addition to the input events. An example of this kind of action event is the one that occurs when the pop-up list of a combo box will be shown or hidden.
Property API
JavaFX includes the Property interface, which extends property handling and binding with some great features and a simple but powerful API. Most of the JavaFX beans use the property API to grant access to their fields. Normally, next to the getter and setter methods, there is a new method to access the property. Here is an example for a DoubleProperty instance:
image
image
As you can see, there is no double cellWidth field in the code. Instead, the attribute is wrapped in a property instance. The getter and setter methods work directly with the property instance and set or request the current value from the property. JavaFX offers a set of basic property classes for primitive data types like String or double. All these basic implementations are part of the package javafx.beans.property.* Next to all these Simple**Property classes, there are some special implementations, such as read-only implementations, that can be used if you want to close your field to external changes. In this case, only removing the setter method is not enough because you can still access the property instance. It’s recommend you use ReadOnly**Property classes, like ReadOnlyDoubleProperty in this case.
By using this design for properties in JavaFX, you will get a lot of benefits in your code. First, JavaFX properties offer support for javafx.beans.value.ChangeListener. So, you can add listeners to every property, as shown here:
image
image
Second, JavaFX properties have support for binding. For this, the Property interface offers the following methods:
imagevoid bind(javafx.beans.value.ObservableValue other);
imagevoid unbind();
imageboolean isBound();
imagevoid bindBidirectional(javafx.beans.property.Property other);
imagevoid unbindBidirectional(javafx.beans.property.Property other);
By using these methods, you can create bindings between JavaFX properties easily. For instance, you can use a binding to express a direct relationship between variables. Changes made to an object will be automatically reflected to any bound object. In the following example, the value of a slider will be bound to another one. Now whatever slider is changed, the other one will adopt its value.
image
image
JavaFX provides two types of binding: bidirectional and unidirectional. The slider example uses a bidirectional binding. With this binding, you can change any of the two sliders, and the other one will change. With the use of the bind(…) method, you can create a unidirectional binding. Here, only one property is bound to the other one: Changing the first slider will affect the second one, but if you change the second slider, this will have no effect on the first one.
With the shown methods, you can easily bind two or more properties with the same value type, but sometimes you need a more complex binding. Suppose you need to bind a slider value to the visible property of a label. The label should appear once the slider value reaches a maximum. The JavaFX property API offers some conversion methods for these needs. Most property types provide specific methods that create a new binding. Here is a sample that uses some of these methods:
image
image
In line 3, the valueProperty is converted to a new double binding that is always double the size of the wrapped property. Now by calling the greaterThan(…) method, you create a Boolean binding that is wrapped around the double binding. This binding’s value is true while the wrapped value is > 100. So if the value of the slider is greater than 50 (50 * 2 > 100), the label will be visible. In addition to these functions, there is the utility class javafx.beans.binding.Bindings that provides a lot of additional functions and support.
Collections
JavaFX offers some new collection types by extending the List, Map, and Set interfaces. All of these can be found in the javafx.collections package. All the new collections are observable and offer support for change listeners. By using the ObservableList, for example, you can easily register a ListChangeListener to receive events for each change that is made to the content of the list. Here is a code snippet that shows how you can use this API:
image
image
As you can see in the code of the ListChangeListener, you can analyze the change that was done on the list content and check what ranges have changed and what kind of change it was. Additionally, there is a utility class called FXCollections. If you know the java.util.Collections class, you will be familiar with this new utility class. By using the class, you can simply create new instances of the JavaFX collection types or execute special operations such as shuffling the content of a list. In the previous code snippet, the FXCollections class is used to create the ObservableList instance.
Concurrent API
As previously stated, JavaFX is a single-threaded system. All rendering and interaction happen on the JavaFX application thread. Much of the time, you need more than one thread in your application. If you want to access a database, for example, you shouldn’t do this on the application thread. The action can block the thread for a long time, and the result will be a frozen application because the thread can’t be used for rendering and user interaction. To help the developer in these cases, JavaFX contains some helper classes to create asynchronous activities. The javafx.concurrent package contains the Worker interface that provides APIs that are useful for creating background workers that will communicate with the UI. The two classes Task and Service implement the Worker interface.
In addition to these classes, the Platform.runLater(…) method is useful. With the help of this method, a runnable can be executed on the JavaFX application thread. (Swing developers may know the equivalent method SwingUtilities.invokeLater(…).)
Animations
As a modern UI toolkit, JavaFX offers a great API to create animations. JavaFX supports two different types of methods to create animation: transitions and timeline animations. A transition is the easiest way to create an animation. By using a specific transition class, you only need to define the values that should be reached by the animation and the duration. Additionally, you can define more properties that will influence the behavior of the transition. Here is a short example of a transition that fades a rectangle out and in when it’s running:
image
image
Timeline animations are more complex than transitions. These animations provide the ability to change properties along the progression of time. Unlike transitions, you can add keyframes to timeline animations and define values at certain times.
FXML
To separate the view definition and the application logic, you can use FXML to define the view. FXML is an XML-based language that defines the structure of a user interface. By using FXML, designers can define the complete user interface of an application without mastering any Java code. The FXML files can be loaded at runtime and don’t need to be compiled. A basic view structure that is defined in an FXML file looks like the following code:
image
image
FXML is the preferred way to define the views of applications in JavaFX. FXML supports all the default JavaFX controls, and you can use FXML to lay out reusable components such as a login form. FXML supports custom controls, too. Because of this, it will be used in later chapters of this book.
CSS Support
All JavaFX controls can be skinned by CSS. Each control has a set of properties, such as foreground color or font size, that are related to its appearance onscreen, and these properties can be defined by CSS. A perfect example that shows what you can do with CSS in JavaFX is the AquaFX library that provides skins to all the default JavaFX controls to make them look like native Mac OS controls. You can find the open source library and documentation at http://aquafx-project.com.
By using CSS, you can define a new look for a control type or a single instance. The following code snippet shows some CSS code that skins a single button:
image
image
When working with controls or creating custom ones, you will normally work a lot with CSS and its internal JavaFX APIs. JavaFX’s support for CSS will be covered later in this book.
Printing
With version 8, APIs for printing support were added to JavaFX. By using these APIs, you can easily print nodes or a complete scene graph from a JavaFX application. This book will not cover printing in detail. To take a short look at the API and its methods, the following code snippet contains a method that can be used to print a JavaFX node:
image
image
Interoperability with Swing
JavaFX offers support to include JavaFX in Swing, and vice versa. As a result, the migration from Swing to JavaFX can be much easier for a Swing-based application. The complete APIs that are provided by JavaFX in this context will be shown later in the book.
Tools
In addition to the general support in the most popular IDEs, there are already some visual tools to help developers create applications with JavaFX. The three most prominent tools are covered here.
All three tools should be known to JavaFX application developers and are also used in some of the examples in this book.
Scene Builder
By using Scene Builder, developers can quickly create attractive graphical interfaces. Developers can easily add graphical components via drag and drop to the working view and lay out all controls of a dialog by using a WYSIWYG editor. In addition, new styles and style sheets can be configured and stored. The created views will be stored as FXML files. These FXML files can be embedded in any JavaFX application and used to represent the view of the application. Scene Builder is much more than a simple layout tool for dialogs. Thanks to its direct support of CSS transformations, effects, and other JavaFX technologies, you can create complex graphical views using Scene Builder. Figure 2-5 shows Scene Builder.
image
image
image
FIGURE 2-5.Scene Builder workspace
Scenic View
Three of the JavaFX chief developers (Jasper Potts, Jonathan Giles, and Richard Bair) run a blog where they introduce interesting JavaFX features and news; see http://fxexperience.com. Additionally, they offer the Scenic View tool for download on this blog (http://fxexperience.com/scenic-view/). With the help of this tool, it is possible to analyze the scene graph. You can look at the layout and the transformation of individual nodes or even directly edit their properties. You should use the Scenic View application primarily to find bugs and check a view for pixel perfection. Figure 2-6 shows Scenic View.
image
image
image
FIGURE 2-6.Scenic View
FX Experience Tools
In addition to the tool Scenic View, the FX Experience blog offers another tool named FX Experience Tools. You can download the code and the application at GitHub. You will find more information about the tool here: http://fxexperience.com/2012/03/announcing-fx-experience-tools/.
You can use the tool to customize the skin of an application. Although you may not create completely self-created skins, you can easily configure the basic colors of a graphical interface and create a blue skin, for example. Figure 2-7 shows FX Experience Tools.
image
image
image
FIGURE 2-7.FX Experience Tools
Deployment/Native Builds
Java provides different ways to deploy a JavaFX application. An application can be packed in a JAR that can be started by a double-click, for example. This way is well known to most developers and is not anything special. Since Java 8, the javafxpackager tool allows you to create self-contained, native applications. By using this tool, you can create an app that is more user friendly than a simple JAR. These applications include all application resources, the Java and JavaFX runtimes, and a launcher. By using them, the user will have the same experience as when installing or launching a native application. By using the javafxpackager tool, an application can be distributed as one of the following formats:
image  ZIP file
image  EXE or MSI for Windows
image  DMG for Mac OS
image  RPM or DEB for Linux
To create a native self-contained application by using the javafxpackager tool, you should read the documentation of the tool, available at the command line. Most important for this goal are the -deploy and -native flags. Here is a short example for a shell command that will create a native installer of a demo application:
image
image
All of JavaFX’s functionality can be used in ANT, too. JavaFX contains a JAR with some specific ANT tasks. The <fx:deploy> task needs to be used in an ANT script to create a self-contained app.
JavaFX Goes Polyglott
Thanks to JSR-223, Scripting for the Java Platform, several scripting languages are available on the JVM. You can simply use JavaFX classes in these scripting languages, and there are frameworks that integrate JavaFX with these script languages in a more natural way. It is not part of this book to teach you how to program in these script languages, but because some of them are currently very popular, some projects may depend on them. The following is a brief overview of the three most important script languages.
GroovyFX
With GroovyFX, you can use JavaFX in Groovy in a much simpler and more natural way. By using the Groovy Builder patterns, you can eliminate boilerplate code and create code that is easier to write and read, and then simply use JavaFX in Groovy without this framework. GroovyFX is open source and can be downloaded here: http://groovyfx.org. You can see the convenience of the code by creating a HelloWorld application. To create a JavaFX application, you need only to pass a closure to the GroovyFX.start(…) method. Inside the closure, you can define the complete UI. The following code shows a simple HelloWorld Groovy application that uses GroovyFX. Figure 2-8 shows the running application.
image
image
image
FIGURE 2-8.GroovyFX application
image
image
ScalaFX
Next to Groovy, Scala is the most successful programming language that can run on top of the JVM. You can find a good introduction to Scala at the Typesafe website (http://typesafe.com/platform/tools/scala), which was founded by the creators of Scala in 2011 and which provides support for Scala. If you want to write a Scala-based JavaFX application, you should take a look at ScalaFX, which is a domain-specific language (DSL) written within Scala that sits on top of JavaFX. Thanks to this, you can use a simple pattern to define the scene graph of your application. Here is a short example of a Scala application that defines a JavaFX view by using ScalaFX:
image
image
ScalaFX is open source software. You can find the download and some documentation on the ScalaFX website: https://code.google.com/p/scalafx/.
JavaFX and Nashorn
The Nashorn engine is a new part of Java SE 8 and provides a lightweight, high-performance JavaScript runtime on the JVM. It enables Java developers to embed JavaScript in Java applications or develop free-standing JavaScript applications that can be on top of the JVM by using the jjs command-line tool. You can easily interpret a JavaFX application that is written in JavaScript with Nashorn by only adding the -fx flag. For example, the following command starts Nashorn to run the javaFX.js file:
image
image
Nashorn provides some additional features to make developing JavaFX applications with JavaScript even easier. Most of the JavaFX classes are wrapped in scripts. By loading them, the imports of JavaFX are easily managed. Here are some examples:
Script
Managed Imports
fx:base.js
javafx.stage.Stage
 
javafx.scene.Scene
 
javafx.scene.Group
 
javafx.beans.*
 
javafx.collections.*
 
javafx.events.*
 
javafx.util-*
fx:fxml.js
javafx.fxml.*
Additionally, the primary stage of a JavaFX application is available in Nashorn as the global property $STAGE. By using this property, you can directly define your application view without using the Application class. Here is a JavaScript example that will run in Nashorn and that creates a simple JavaFX application:
image
image
Summary
In this chapter, I covered the basics of JavaFX, including its APIs, tools, and JVM support. You quickly saw that even in the case of a simple HelloWorld example, JavaFX calls on a number of different APIs. All these APIs will be elaborated on in the following chapters.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.126.56