image
CHAPTER
7
Additional JavaFX Nodes
JavaFX contains a set of extra node classes that you can use to represent specific data and content onscreen. These nodes do not extend the Control class, so I will discuss them separately in this chapter because of their special functions and behavior. This chapter will introduce these special nodes and show how to use them by illustrating the following node types:
imageCharts
imageWebView
imageCanvas
imageImageView
imageMediaView
Most of these components provide a huge set of functionality, but I will focus on the core features and common use cases.
Charts
JavaFX contains an API to create modern charts. All chart types in JavaFX extend the Chart class, which extends Node. Here are the types of charts that JavaFX supports:
imagePieChart
imageBubbleChart
imageStackedAreaChart
imageScatterChart
imageBarChart
imageAreaChart
imageLineChart
imageStackedBarChart
With the exception of the PieChart, all chart types are defined as x-y charts. This means that all values in these charts are shown in x-y coordinate systems, and often the x-axis defines different types or categories instead of a range of values. Except for the PieChart class, all charts extend the basic class XYChart<X,Y>. As you can see, the type of the x- and y-axis is defined by generics. Figure 7-1 shows an overview of all the chart types.
image
image
image
FIGURE 7-1.Chart types in JavaFX
Let’s first look at the PieChart. Like the other charts, the PieChart class extends the Node class and can be added to a scene graph like any other node. The following code snippet shows how to create a PieChart:
image
image
As you can see, the chart needs an ObservableList<PieChart.Data> as its data model. The PieChart.Data class defines a tuple where a value is mapped to a numeric value. From this list, the control renders the top-left chart in Figure 7-1. All chart types define properties that you can use to change the rendering and behavior of the chart. Although all the properties of the chart nodes won’t be shown here, you can find a comprehensive list in the JavaDoc of the chart classes.
image
NOTE
For all chart types, the ObservableList is used to define the data of the chart so the chart can observe its data and react dynamically whenever the data changes. In other words, all charts will update its view whenever the data changes via an animation. You use the animated property of the Chart class to toggle this functionality. In an XYChart, you can even access the axis and define animations for both the axis and its range.
As mentioned earlier, all other chart classes extend the XYChart. Given this similarity, I’ll show one example here. The following code snippet creates the AreaChart that is shown at the bottom-left corner of Figure 7-1:
image
image
Data can be defined for all two-axis chart series, and these series are defined by the XYChart.Series<X,Y> class. In the example, both axes are numeric, so the example uses XYChart.Series<Number,Number>. Each series can be defined by a name, and each series can contain data tuples that map an x-value to a y-value. These tuples are defined by the XYChart.Data<X,Y> class. In the example code, you can see how to add data to a series. The Series class contains a name property of type StringProperty that will hold the name of the series. Also, as shown in the example, a chart can contain several series of data. The XYChart class defines the data property of type ObjectProperty<ObservableList<Series<X,Y>>> that will hold all the data series. You can use this workflow for all the chart types.
In addition to the data rendering, each chart contains a legend with an overview of the different data series that are rendered in the chart. The visual appearance of the legend and the chart can be configured by properties or by CSS. (Chapter 9 shows an example of how a chart can be styled by CSS.) Here are some examples of settings that can be changed in code or CSS:
image  The label of the axis
image  Minimum and maximum tick marks
image  The gap between tick marks
image  The position of the legend
image
NOTE
Like most of the other more complex node types in JavaFX, the charts internally are constructed by several nodes. In a BarChart, each bar in the diagram is a node in the scene graph. You can access these nodes using the node property of the XYChart.Data<X,Y> class. In fact, more advanced developers can apply visual effects to these nodes or transform them whenever a mouse hovers over a bar in a BarChart, for example.
WebView
JavaFX supports the rendering of HTML content with the help of the WebView. A WebView is a node that renders a web page into the scene graph. Unlike in older UI toolkits, WebView supports dynamic as well as static HTML pages. The node uses WebKit internally to render the defined page. WebKit is an HTML rendering engine that is used in browsers such as Apple Safari. Therefore, the WebView supports all the HTML, CSS, and JavaScript features that are supported by WebKit. Additionally, the WebView contains a WebEngine that can be used to interact with the defined page or to execute JavaScript, for example. The following application uses a WebView and loads any web page:
image
image
When starting the application, you can enter a custom URL in the text field. After pressing ENTER, the web page will be loaded and rendered in the WebView. Figure 7-2 shows an example of a loaded page. As you can see in the code, all interaction with the HTML content of the WebView is performed on the WebEngine. You access the engine by using the getEngine() method of the WebView. To load a custom page, the engine offers a load(…) method. In the sample, this method is invoked whenever the ENTER key is pressed in the text field. In addition to the TextField and the WebView, the example application uses a ProgressBar control, and the progress property of this progress bar is bound to the load progress of the current site. In Figure 7-2, most of the data of the defined web site has loaded, and like in all modern web browsers, the loaded parts of the page are shown on the screen. But as you can see in the figure, some content has not loaded because the progress bar is not completely filled.
image
image
image
FIGURE 7-2.WebView that renders a web page
The WebView node offers some properties that can be used to define the visual rendering of a web page. This can be done in a JavaFX application too. Table 7-1 contains the properties of the WebView class.
image
TABLE 7-1.Properties of the WebView
All interaction with the web page and the JavaScript support is wrapped in the WebEngine class, which offers a set of properties to define the behavior of the web page and the handling of JavaScript. To understand some of these properties, you need a basic knowledge of JavaScript and web development. I won’t discuss these properties in depth here, but you can see an overview of them in Table 7-2.
image
image
TABLE 7-2.Properties of the WebEngine
In addition to these properties, the WebEngine class offers several useful methods, including the one that is shown in the demo application, which loads and renders new content in WebView by calling the load(String url) method of the engine. In addition to the load(…) method, the content of a WebView can be reloaded or a custom script can be executed in the context of the current web page. Table 7-3 shows the public methods of the WebEngine class.
image
TABLE 7-3.Methods of the WebEngine
The following example uses some of the properties that are part of the WebView. These properties will affect the rendering of the web page. In the example, the font scale and zoom are defined. For both of these properties, 1.0 is the default value. By setting the two properties to 1.5, all fonts on the rendered page will appear in a bigger size and the page will be zoomed in. Figure 7-3 shows the same web site as before that is now rendered by a WebView with the changed properties.
image
image
image
FIGURE 7-3.A customized WebEngine
image
image
image
NOTE
Because the WebView and all other components that are shown in this chapter are nodes in a scene graph, they can be easily transformed like any other node object. To do that, you define a rotation for the WebView, as shown in Chapter 3. The following code snippet shows how this can be done:
image
The zoom property of the WebView is used by the WebKit internally, and the page is rendered in the defined zoom. If you scale the WebKit as described in Chapter 3, it can end in blurry pixels because JavaFX will scale the rendered result that is pixel based and not vector based.
As mentioned, WebView and the WebKit-based engine support JavaScript. The following example shows how JavaScript can be used to create interaction between web content and JavaFX. The demo is a simple HTML page containing a small JavaScript section. In the script, the alert(…) function will be called. This function is a JavaScript default function that normally will create a pop-up that is shown onscreen. The script will be executed when a hyperlink on the page is clicked.
image
image
The HTML file can be opened with a web browser like Chrome or Safari. Once the hyperlink is clicked, an alert dialog will be shown. The dialog contains the alert message. In JavaFX you can define a handler for the alert(…). The following application loads the HTML file in a WebView and defines a special handler for JavaScript alert(…) executions:
image
image
Whenever the hyperlink is clicked in the WebView, the alert handler will fire an event, and a message will be printed on the console. As shown in Table 7-2, the WebEngine class provides the ability to define different handlers for default JavaScript functions in addition to the alert one. The application uses an additional property of the engine too. The title property of the WebEngine is bound to the title of the JavaFX stage. As you can see in the HTML file, the title of the web page is defined as Alert Demo. Once the page is loaded in the application, the title of the window will change to the one defined in the web page.
Beyond this simple example, the WebEngine provides everything needed to create complete interaction between HTML content and JavaFX. Anyone familiar with JavaScript can integrate a web application in a JavaFX application and use the best features from both worlds.
Canvas
The Canvas node in JavaFX is comparable to the HTML5 canvas or the Graphics2D class from Java2D. The Canvas can be used to draw any figure, image, or collage onscreen. Like the Canvas objects in other programming languages, the Canvas node provides a graphics context that has all the needed methods to draw lines, splines, shapes, or images in the canvas. In JavaFX, the graphics context is defined by the GraphicsContext class, and you can retrieve the context by calling the canvas.getGraphicsContext2D() method. The class provides a set of graphics commands, and if you have used a canvas-based API before, you will be familiar with these methods. This book won’t cover all of these methods, but a good overview is available in the JavaDoc of the GraphicsContext class.
The following example uses a Canvas node and draws some figures on it:
image
image
As you can see, the Canvas object isn’t created with an empty constructor. Here, the width and height of the node are defined. Because a canvas can contain any drawing, it can’t know its own size, so you need to specify the size of a canvas. In the example code, some figures are drawn by using the GraphicsContext of the Canvas. Figure 7-4 shows the result of this drawing.
image
image
image
FIGURE 7-4.The Canvas node
The Canvas and the GraphicsContext won’t clear the drawing in the canvas. Unlike in Swing where the internal API clears the complete canvas with each repaint, you need to do this by hand in JavaFX. As a result, the JavaFX Canvas API is more flexible. The following sample defines an interactive canvas. Rectangles can be drawn in the canvas by mouse clicks. In addition, the canvas can be cleared.
image
image
image
image
The class defines three methods that will draw in the canvas: The fill(…) method will fill the complete canvas with a custom color, the clear(…) method will clear the canvas, and the stamp(…) method will add a rectangle to the canvas. By adding an event handler for mouse events to the Canvas, you can add rectangles to the Canvas, as shown in Figure 7-5.
image
image
image
FIGURE 7-5.An interactive Canvas
Some drawing features of the Canvas are not shown in the demo applications. For example, the GraphicsContext provides a great path API that can be used to draw a path with Bézier curves on the screen. Furthermore, images can be drawn.
image
NOTE
JavaFX provides a lot of basic shapes, such as rectangles and lines, as nodes that can be used directly in the scene graph. Some developers may ask themselves why the Canvas node is needed in addition to these shapes. Each node in JavaFX contains basic functionalities such as CSS support, skinning, and a lot of properties. Sometimes, this is not needed, and when drawing in a Canvas, this “overhead” doesn’t apply. All the nodes need to be added to the scene graph, and panes must provide the layout for them. In a Canvas, a developer can draw shapes by simply defining x-y coordinates. In addition, shapes that are drawn to a Canvas don’t exist as object instances and can’t be changed in the future. In some special cases, using the Canvas is much faster and provides more performance than defining all drawings in the scene graph.
ImageView
The ImageView is the default component to show any image in a defined size in a scene graph. To do so, you need an image as defined by the Image class in JavaFX. The following example shows how to use the ImageView node:
image
image
The code loads an image that is part of the classpath and is stored in the same package as the Application class. The loaded image will be shown in an ImageView and is defined by an instance of the Image class. Because the ImageView is always maximized in the sample application window and the image might be smaller or bigger than the ImageView, a binding is used in the example. The width and the height of the StackPane that is the parent of the ImageView are bound to the size of the image. By doing it this way, the window can be resized, and the image will always fit perfectly into it. Additionally, the preserveRatio property of the ImageView node is set. As a result, the ImageView will always preserve the aspect ratio of the image when resizing it. Figure 7-6 shows the application.
image
image
image
FIGURE 7-6.An ImageView
The ImageView class defines a set of properties that can be used to change the rendering of the defined image. Some of them, such as the preserveRatio property, are used in the example. Table 7-4 contains all properties of the ImageView class.
image
TABLE 7-4.Properties of the ImageView Class
The ImageView always needs an Image object to render anything onscreen. An Image object is always defined by the Image class, whose properties are shown in Table 7-5.
image
TABLE 7-5.Properties of the Image Class
The Image class also provides some constructors that can be used to load an image. These constructors support different sources and options; Table 7-6 gives an overview of the parameters that can be found in the constructors of the Image class. As you can see, an image can be loaded by an URL or a stream. Currently, JavaFX supports JPEG, PNG, GIF, and BMP images. The API to add image types is still private in JDK 8. If a custom image is needed or if the visual content of an image needs to be changed, you should use the WriteableImage. This class extends the Image class and offers a PixelWriter to set the RGB value of specific pixels. You can access the writer by using the getPixelWriter() method. In addition, the Image class contains the getPixelReader() method that offers a PixelReader that provides access to the pixels of an image. With the help of these two methods, images can be easily changed. As a result, you can create custom filters that change the saturation or brightness of an image, for example.
image
TABLE 7-6.Constructor Parameters of the Image Class
image
NOTE
JavaFX supports animated images too. A GIF, for example, can be animated. This image can be loaded by the Image class like any other image. You can use the isAnimation() method of the Image class to check whether an image is animated. If an image is animated, a PixelReader can’t be used. In this case, the pixelsReadable() method of the image instance will return false.
MediaView
The MediaView is a JavaFX control that can render video playback onscreen. The MediaView internally uses the JavaFX media API, and this API is defined in the javafx.scene.media package. The API can be used to play audio too. Because the MediaView is shown here, the following description is limited to video support.
The following video formats are currently supported by JavaFX:
image  FLV containing VP6 video and MP3 audio
image  MPEG-4 multimedia container with H.264/Advanced Video Coding (AVC) video compression
image
NOTE
On some older Windows versions and Linux systems, additional software packages may be needed to support specific video codecs. Information about these topics can be found in the JavaFX system requirements: http://docs.oracle.com/javafx/release-documentation.html.
The following example shows how to display a video in a JavaFX application:
image
image
As you can see in the code, the video is defined as a Media instance. Here, the path to the video data is assigned as a URL to the Media constructor. To play any media in JavaFX, you need a MediaPlayer instance. A player contains one Media instance that can be played, and the MediaPlayer defines different methods to handle the playback of the media. In the sample, the play() method is used. This method starts the playback. To render the video onscreen, you need a MediaView. When starting the sample, the video will be directly shown on the screen.
The MediaPlayer class provides a lot of useful methods and properties that can be used to handle the playback of the video, the audio volume, and other useful functionalities. By using these methods, the media playback can become interactive. It is easy to create “play” and “pause” buttons, for example. The following code shows how to define these methods:
image
image
Summary
All the node types covered in this chapter are great benefits of JavaFX because the nodes provide the ability to render different data types on the screen. Developers can add movies with the help of the MediaView to an application or render business data by using the chart API. Thanks to native dependencies such as WebKit and different video codecs, JavaFX provides state-of-the-art rendering for the mentioned data types. You won’t find these visual components and their features in the basic APIs of older Java UI toolkits. With the use of the JavaFX APIs, it is easy to enrich an application, and I think that this will happen in a lot of desktop applications in the next years.
..................Content has been hidden....................

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