How colors are represented in JavaFX
What different color patterns are
How to use an image pattern
How to use a linear color gradient
How to use a radial color gradient
Understanding Colors
A uniform color, an image pattern, a linear color gradient, and a radial color gradient are instances of the Color, ImagePattern, LinearGradient, and RadialGradient classes, respectively. The Stop class and the CycleMethod enum are used while working with color gradients.
Typically, methods for setting the color attribute of a node take the Paint type as an argument, allowing you to use any of the four color patterns.
Using the Color Class
Using the constructor
Using one of the factory methods
Using one of the color constants declared in the Color class
Color color(double red, double green, double blue)
Color color(double red, double green, double blue, double opacity)
Color hsb(double hue, double saturation, double brightness)
Color hsb(double hue, double saturation, double brightness, double opacity)
Color rgb(int red, int green, int blue)
Color rgb(int red, int green, int blue, double opacity)
The Color class defines about 140 color constants, for example, RED, WHITE, TAN, and BLUE, among others. Colors defined by these constants are completely opaque.
Using the ImagePattern Class
- 1.
Create an Image object using an image from a file.
- 2.
Define a rectangle, known as the anchor rectangle, relative to the upper-left corner of the shape to be filled.
The image is shown in the anchor rectangle and is then resized to fit the anchor rectangle. If the bounding box for the shape to be filled is bigger than that of the anchor rectangle, the anchor rectangle with the image is repeated within the shape in a tiling pattern.
ImagePattern(Image image)
ImagePattern(Image image, double x, double y, double width, double height, boolean proportional)
Using an Image Pattern to Fill Different Shapes
Understanding Linear Color Gradient
A linear color gradient is defined using an axis known as a gradient line . Each point on the gradient line is of a different color. All points on a line that is perpendicular to the gradient line have the same color, which is the color of the point of intersection between the two lines. The gradient line is defined by a starting point and an ending point. Colors along the gradient line are defined at some points on the gradient line, which are known as stop-color points (or stop points). Colors between two stop points are computed using interpolation.
The gradient line has a direction, which is from the starting point to the ending point. All points on a line perpendicular to the gradient line that pass through a stop point will have the color of the stop point. For example, suppose you have defined a stop point P1 with a color C1. If you draw a line perpendicular to the gradient line passing through the point P1, all points on that line will have the color C1.
Using the LinearGradient Class
LinearGradient(double startX, double startY, double endX, double endY, boolean proportional, CycleMethod cycleMethod, List<Stop> stops)
LinearGradient(double startX, double startY, double endX, double endY, boolean proportional, CycleMethod cycleMethod, Stop... stops)
The startX and startY arguments define the x and y coordinates of the starting point of the gradient line. The endX and endY arguments define the x and y coordinates of the ending point of the gradient line.
The proportional argument affects the way the coordinates of the starting and ending points are treated. If it is true, the starting and ending points are treated relative to a unit square. Otherwise, they are treated as absolute values in the local coordinate system. The use of this argument needs a little more explanation.
Typically, a color gradient is used to fill a region, for example, a rectangle. Sometimes, you know the size of the region, and sometimes you will not. The value of this argument lets you specify the gradient line in relative or absolute form. In relative form, the region is treated as a unit square. That is, the coordinates of the upper-left and the lower-right corners are (0.0, 0.0) and (1.0, 1.0), respectively. Other points in the regions will have x and y coordinates between 0.0 and 1.0. Suppose you specify the starting point as (0.0, 0.0) and the ending point as (1.0, 0.0). It defines a horizontal gradient line from left to right. The starting and ending points of (0.0, 0.0) and (0.0, 1.0) define a vertical gradient line from top to bottom. The starting and ending points of (0.0, 0.0) and (0.5, 0.0) define a horizontal gradient line from the left to the middle of the region.
When the proportional argument is false, the coordinate values for the starting and ending points are treated as absolute values with respect to the local coordinate system. Suppose you have a rectangle of width 200 and height 100. The starting and ending points of (0.0, 0.0) and (200.0, 0.0) define a horizontal gradient line from left to right. The starting and ending points of (0.0, 0.0) and (200.0, 100.0) define a diagonal gradient line from the top-left corner to the bottom-right corner.
CycleMethod.NO_CYCLE
CycleMethod.REFLECT
CycleMethod.REPEAT
The cycle method of NO_CYCLE fills the remaining region with the terminal color. If you have defined color a stop point only from the left to the middle of a region, the right half will be filled with the color that is defined for the middle of the region. Suppose you define a color gradient for only the middle half of a region, leaving the 25% at the left side and 25% at the right side undefined. The NO_CYCLE method will fill the left 25% region with the color that is defined at the 25% distance from left and the right 25% region with the color defined at the 25% distance from right. The color for the middle 50% will be determined by the color-stop points.
The cycle method of REFLECT fills the remaining regions by reflecting the color gradient, as start-to-end and end-to-start, from the nearest filled region. The cycle method of REPEAT repeats the color gradient to fill the remaining region.
The offset value is between 0.0 and 1.0. It defines the relative distance of the stop point along the gradient line from the starting point. For example, an offset of 0.0 is the starting point, an offset of 1.0 is the ending point, an offset of 0.5 is in the middle of the starting and ending points, and so forth. You define at least two stop points with two different colors to have a color gradient. There are no limits on the number of stop points you can define for a color gradient.
That covers the explanation for the arguments of the LinearGradient constructors. So let’s look at some examples on how to use them.
In this code, you have made a slight change. You defined a horizontal gradient line, which starts at the left side of the rectangle and ends in the middle. Note the use of (0.5, 0) as the coordinates for the ending point. This leaves the right half of the rectangle with no color gradient. The cycle method is effective in this case as its job is to fill the unfilled regions. The color at the middle of the rectangle is black, which is defined by the second stop point. The NO_CYCLE value uses the terminal black color to fill the right half of the rectangle.
Defining Linear Color Gradients Using a String Format
Using two points—the starting point and the ending point
Using a side or a corner
The side-or-corner value may be top, left, bottom, right, top left, bottom left, bottom right, or top right. When you define the gradient line using a side or a corner, you specify only the ending point. The starting point is inferred. For example, the value “to top” infers the starting point as “from bottom,” the value “to bottom right” infers the starting point as “from top left,” and so forth. If the gradient-line value is missing, it defaults to “to bottom.”
The valid values for the cycle-method are repeat and reflect. If it is missing, it defaults to NO_CYCLE. It is a runtime error to specify the value of the cycle-method argument as NO_CYCLE. If you want it to be NO_CYCLE, simply omit the cycle-method argument from the syntax.
white, black
white 0%, black 100%
white 0%, yellow 50%, blue 100%
white 0px, yellow 100px, red 200px
When you do not specify positions for the first and the last color stops, the position for the first one defaults to 0% and the second one to 100%. So, the color stop lists "white, black" and "white 0%, black 100%" are fundamentally the same.
white, yellow, black, red, green
white 0%, yellow 25%, black 50%, red 75%, green 100%
white, yellow, black 60%, red, green
white 0%, yellow 30%, black 50%, red 80%, green 100%
Understanding Radial Color Gradient
A gradient shape (the center and radius of the gradient circle)
A focus point that has the first color of the gradient
Color stops
The list of color stops determines the value of the color at a point inside the gradient shape. The focus point defines the 0% position of the color stops. The points on the periphery of the circle define the 100% position for the color stops. How would you determine the color at a point inside the gradient circle? You would draw a line passing through the point and the focus point. The color at the point will be interpolated using the nearest color stops on each side of the point on the line.
Using the RadialGradient Class
RadialGradient(double focusAngle, double focusDistance, double centerX, double centerY, double radius, boolean proportional, CycleMethod cycleMethod, List<Stop> stops)
RadialGradient(double focusAngle, double focusDistance, double centerX, double centerY, double radius, boolean proportional, CycleMethod cycleMethod, Stop... stops)
The focusAngle argument defines the focus angle for the focus point. A positive focus angle is measured clockwise from the horizontal line passing through the center point and the line connecting the center point and the focus point. A negative value is measured counterclockwise.
The focusDistance argument is specified in terms of the percentage of the radius of the circle. The value is clamped between –1 and 1. That is, the focus point is always inside the gradient circle. If the focus distance sets the focus point outside the periphery of the gradient circle, the focus point that is used is the point of intersection of the periphery of the circle and the line connecting the center point and the set focus point.
The centerX and centerY arguments define the x and y coordinates of the center point, respectively, and the radius argument is the radius of the gradient circle. These arguments can be specified relative to a unit square (between 0.0 and 1.0) or in pixels.
The proportional argument affects the way the values for the coordinates of the center point and radius are treated. If it is true, they are treated relative to a unit square. Otherwise, they are treated as absolute values in the local coordinate system. For more details on the use of the proportional argument, please refer to the section “Using the LinearGradient Class” earlier in this chapter.
JavaFX lets you create a radial gradient of a circular shape. However, when the region to be filled by a radial color gradient has a nonsquare bounding box (e.g., a rectangle) and you specify the radius of the gradient circle relative to the size of the shape to be filled, JavaFX will use an elliptical radial color gradient. This is not documented in the API documentation of the RadialGradient class. I will present an example of this kind shortly.
The cycleMethod and stops arguments have the same meaning as described earlier in the section on using the LinearGradient class. In a radial color gradient, stops are defined along lines connecting the focus point and points on the periphery of the gradient circle. The focus point defines the 0% stop point, and the points on the circle periphery define 100% stop points.
The zero value for the focus angle and focus distance locates the focus point at the center of the gradient circle. A true proportional argument interprets the center point coordinates (0.5, 0.5) as (25px, 25px) for the 50 by 50 rectangular bounds of the circle. The radius value of 0.5 is interpreted as 25px, and that places the center of the gradient circle at the same location as the center of the circle to fill. The cycle method of NO_CYCLE has no effect in this case as the gradient circle fills the entire circular area. The color stop at the focus point is white, and at the periphery of the gradient circle, it is black.
Criteria Used to Determine the Shape of a Radial Color Gradient
Proportional Argument | Bounding Box for the Filled Region | Gradient Shape |
---|---|---|
true | Square | Circle |
true | Nonsquare | Ellipse |
false | Square | Circle |
false | Nonsquare | Circle |
I should emphasize here that, in the preceding discussion, I am talking about the bounds of the regions to be filled, not the region. For example, suppose you want to fill a triangle with a radial color gradient. The bounds of the triangle will be determined by its width and height. If the triangle has the same width and height, its bounds take a square region. Otherwise, its bounds take a rectangular region.
Defining Radial Color Gradients in String Format
The arguments within square brackets are optional. If you do not specify an optional argument, the comma that follows needs to be excluded as well.
focus-angle 45.0deg
focus-angle 0.5rad
focus-angle 30.0grad
focus-angle 0.125turn
focus-distance 50%
center 50px 50px, radius 50px
center 50% 50%, radius 50%
The valid values for the cycle-method argument are repeat and reflect. If this is not specified, it defaults to NO_CYCLE.
white, black
white 0%, black 100%
red, green, blue
red 0%, green 80%, blue 100%
Summary
In JavaFX, you can specify text color and background color for regions. You can specify a color as a uniform color, an image pattern, or a color gradient. A uniform color uses the same color to fill the entire region. An image pattern lets you fill a region with an image pattern. A color gradient defines a color pattern in which the color varies along a straight line from one color to another. The variation in a color gradient can be linear or radial. All classes are included in the javafx.scene.paint package.
The Paint class is an abstract class, and it is the base class for other color classes. A uniform color, an image pattern, a linear color gradient, and a radial color gradient are instances of the Color, ImagePattern, LinearGradient, and RadialGradient classes, respectively. The Stop class and the CycleMethod enum are used when working with color gradients. You can specify colors using instances of one of these classes or in string forms. When you use a CSS to style nodes, you specify colors using string forms.
An image pattern lets you fill a shape with an image. The image may fill the entire shape or use a tiling pattern.
A linear color gradient is defined using an axis known as a gradient line. Each point on the gradient line is of a different color. All points on a line that is perpendicular to the gradient line have the same color, which is the color of the point of intersection between the two lines. The gradient line is defined by a starting point and an ending point. Colors along the gradient line are defined at some points on the gradient line, which are known as stop-color points (or stop points). Colors between two stop points are computed using interpolation. The gradient line has a direction, which is from the starting point to the ending point. All points on a line perpendicular to the gradient line that passes through a stop point will have the color of the stop point. For example, suppose you have defined a stop point P1 with a color C1. If you draw a line perpendicular to the gradient line passing through the point P1, all points on that line will have the color C1.
In a radial color gradient, colors start at a single point, transitioning smoothly outward in a circular or elliptical shape. The shape is defined by a center point and a radius. The starting point of colors is known as the focus point of the gradient. The colors change along a line, starting at the focus point of the gradient, in all directions until the periphery of the shape is reached.
The next chapter will show you how to style nodes in a scene graph using CSS.