Building GUI Applications With JavaFX

An application run on the mobile emulator

Lesson 5: Applying Data Binding to UI Objects


The goal of this application procedure is to draw a slider and a circle whose center is bound to the slider's value. The interior of the circle is painted with a radial gradient pattern. As you move the slider, the circle moves. This example employs the slider component that resides in the javafx.scene.control package, a graphical shape, and a color gradient. The motionless gradient filling gives the circle the impression of the phases of an eclipse. Try to move the slider to explore the following applet in action.

Create an application window with the title "Data Binding", a width of 220 pixels and a height of 170 pixels. For details, see Using Declarative Syntax. The following code creates the window.

import javafx.stage.Stage;
import javafx.scene.Scene;

Stage {
title: "Data Binding"
scene: Scene {
width: 220
height: 170
}//Scene
}//Stage

You add objects to your application window by putting them on the scene of the Stage. For more details, see Presenting UI Objects in a Graphical Scene. For details on the Circle class, see Using Declarative Syntax.

  1. Add import statements for the javafx.scene.shape.Circle and javafx.scene.paint.Color classes.

  2. Define the content variable of the scene by adding the Circle object literal.

    import javafx.stage.Stage;
    import javafx.scene.Scene;
    import javafx.scene.shape.Circle;
    import javafx.scene.paint.Color;

    Stage {
    title: "Data Binding"
    scene: Scene {
    width: 220
    height: 170
    content: Circle {
    centerX: 50
    centerY: 60
    radius: 50
    stroke: Color.YELLOW
    }//Circle
    }//Scene
    }//Stage

    By default, the interior of the circle is black and the background of the scene is white. At this step the output appears as follows.

    A frame with white background and yellow circle
    Figure 1: A circle added to the scene

You can increase the visual attractiveness of the example by adding a specific fill pattern to the circle called radial gradient. Using the radial gradient is what gives the effect of an eclipse when the slider is moved.

To implement this painting feature, use the RadialGradient class. You can specify two or more colors by using the Stop class. The RadialGradient class will provide an interpolation between them. Specify a circle which controls the gradient pattern by defining a center point and a radius. You can also define a focus point within the circle where the first color is applied. The last color is applied to the perimeter of the circle.

For the radial gradient fill pattern, you can specify absolute values for the center, the radius, and the focus. In this case you need to set the proportional variable to false. If the proportional variable is set to true, values for the center, radius, and focus will range from 0.0 to 1.0, and the radial gradient will be scaled to fill the shape it is applied to.

The stops variable defines a sequence of colors for the radial gradient fill pattern. Use square brackets to specify a sequence, and commas to separate its elements. To add a fill pattern to the circle:

  1. Add import statements for the RadialGradient and Stop classes from the javafx.scene.paint package.

  2. Define the fill instance variable using the RadialGradient object literal.

  3. Specify absolute values for a center point and a radius using the centerX, centerY, and radius variables.

  4. Specify the focus point by using the focusX and focusY variables.

  5. Set the proportional variable to false.

  6. Define the stops variable as a sequence of red and white colors.

    import javafx.stage.Stage;
    import javafx.scene.Scene;
    import javafx.scene.shape.Circle;
    import javafx.scene.paint.Color;
    import javafx.scene.paint.RadialGradient;
    import javafx.scene.paint.Stop;

    Stage {
    title: "Data Binding"
    scene: Scene {
    width: 220
    height: 170
    content: Circle {
    centerX: 50 centerY : 60 radius: 50
    stroke: Color.YELLOW
    fill: RadialGradient {
    centerX: 50 centerY : 60 radius: 50
    focusX: 50 focusY: 30
    proportional: false
    stops: [
    Stop {offset: 0 color: Color.RED},
    Stop {offset: 1 color: Color.WHITE}
    ]
    }//RadialGradient
    }//Circle
    }//Scene
    }//Stage

    Compiling and running this modified code produces the following result.

    A frame with a yellow circle and red radial gradient fill pattern
    Figure 2: The circle filled in with the radial gradient pattern

The Slider class from the javafx.scene.control package provides a slider control, a widely known desktop GUI element. Add the slider to the scene and place it below the circle. By default, the slider will be rendered at the point (0,0). You can use the translateX and translateY instance variables to specify distances by which coordinates are translated in the X axis and Y axis directions on the scene. To add a slider, complete the following steps.

  1. Add an import statement for the javafx.scene.control.Slider class.

  2. Add the Slider object literal to the content variable of the scene.

  3. Specify the slider's minimum and maximum values and set the current value to zero.

    import javafx.scene.control.Slider;

    content: [
    Circle {
    ...
    },
    Slider {min: 0 max: 60 value : 0}
    ]

  4. Specify the position of the slider within the scene using the translateX and translateY instance variables.

    content: [
    Circle {
    ...
    },
    Slider {
    min: 0
    max: 60
    value : 0
    translateX: 10
    translateY: 110
    }
    ]

A frame with a slider and a circle filled in with radial gradient
Figure 3: A slider added to the application window

Finally, bind the center of the circle to the slider's value. The slider is displayed in the application window and you can change its value by moving the knob. However, you have no means to refer to the slider's value, which is required for binding. The solution is to define a slider variable and then refer to the slider.value. To define a binding relationship, complete the following steps.

  1. Create the slider variable.

    def slider = Slider {
    min: 0
    max: 60
    value : 0
    translateX: 10
    translateY: 110
    };

  2. Define the binding relationship.

    Circle {
    centerX: bind slider.value+50 centerY: 60 radius: 50
    ...
    }

The bind operator keeps track of any changes in the value on the right. As the slider's value changes, the center of the circle is updated and JavaFX automatically renders the circle at the new location. Since the position of the radial gradient filling does not change, you can see how the circle shifts relative to the initial filling.

In conclusion, the complete code of the data binding example is shown in the following image. Compile, run and explore data binding in action.

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
import javafx.scene.paint.Stop;
import javafx.scene.paint.RadialGradient;

def slider = Slider{min: 0 max: 60 value: 0 translateX: 10 translateY: 110};

Stage {
title: "Data Binding"
width: 220
height: 170
scene: Scene {
content: [
slider,
Circle {
centerX: bind slider.value+50 centerY: 60 radius: 50
stroke: Color.YELLOW
fill: RadialGradient {
centerX: 50 centerY: 60 radius: 50
focusX: 50 focusY: 30
proportional: false
stops: [
Stop {offset: 0 color: Color.RED},
Stop {offset: 1 color: Color.WHITE},
]
}//RadialGradient
}//Circle
]
}//Scene
}//Stage

This application uses classes from the common profile of the JavaFX API, and thus, can be run as a desktop application or on mobile devices. The following screen capture shows how the application will look when run on the mobile emulator.

An application run on the mobile emulator
Figure 4: An application run on the mobile emulator

0 comments:

Post a Comment