2.2 Project GuitarTuner
Project GuitarTuner helps you tune your guitar. It displays a visual guitar fret board with six strings. The letter (note) corresponding to the guitar string appears next to the fret board. When you click a string with the mouse, you’ll hear a synthesized guitar note for the selected string as it vibrates visually. Project GuitarTuner uses the Java javax.sound.midi API to generate the sounds. Figure 2.1 shows this application running when the A string is vibrating. The corresponding JavaFX graphical objects are labeled.
The Scene Graph Metaphor
JavaFX programs with a graphical user interface define a stage and a scene within that stage. The stage represents the top level container for all JavaFX objects; that is, the content area for an applet or the frame for a widget. The central metaphor in JavaFX for specifying graphics and user interaction is a scene graph. A scene defines a hierarchical node structure that contains all the scene’s components. Nodes are represented by graphical objects, such as geometric shapes (Circle, Rectangle), text, UI controls, image viewers, video viewers, and user-created objects (such as GuitarString in our example). Nodes can also be containers that in turn hold more nodes, letting you group nodes together in hierarchical structures. (For example, Group is a general-purpose container node, HBox provides horizontal layout alignment, and VBox provides vertical layout alignment.) The scene graph is this hierarchical node structure.
Figure 2.2 shows the scene graph for project GuitarTuner. Compare the visual graphical elements in Figure 2.1 with the scene graph depicted in Figure 2.2.
In general, to construct a JavaFX application, you build the scene graph, specifying the look and behavior of all its nodes. Then, your application just “runs.” Some applications need input to go—user actions that activate animations or affect component properties. Other applications just run on their own. (Building the scene graph is analogous to winding up a toy. When you’re done, the application just runs.)
Within the scene graph for project GuitarTuner, you see the Scene at the top level, which contains a Group. Within the Group there is a Rectangle for the fret board (the guitar neck), two Line nodes representing frets, and six GuitarStrings. Each GuitarString is in turn its own Group consisting of three Rectangles and a Text node. Nodes that contain other nodes (such as Scene and Group) include a content property that holds subnodes. The hierarchical nature of the scene graph means that all nodes at the same level share the same coordinate space. You therefore build node structures (such as GuitarString) that use a relative coordinate system. You’ll see shortly why this is useful.
The order of nodes within a parent container affects their rendering. That is, the first node in the container is “drawn” first. The final node is “drawn” last and is on top of the view. Nodes (depending on their placement within the coordinate system) may visually block or “clip” previously drawn nodes. In GuitarTuner, the nodes must be in a specific order. You draw the fret board first, then the frets, and finally the guitar strings, which appear on top.
Changing the relative order of nodes in a container is easy. The toFront() function brings a node to the front (top) and the toBack() function sends a node to the back (bottom).
Hierarchical Scene Graph
Figure 2.3 also shows a scene graph of project GuitarTuner. Figure 2.2 and Figure 2.3 depict the same structure, but Figure 2.3 shows the hierarchical relationship among the nodes in the scene using a graphical tree view. Nodes at the same level share the same coordinate space. For example, the three Rectangles and Text nodes in the GuitarString share the same coordinate system.