Java 2D Graphics, The Color Constructors and Transparency
Java Programming, Lecture Notes # 324.
Beginning with JDK 1.2, Graphics2D is the fundamental class for rendering two-dimensional shapes, text and images.
You also need to understand some other classes and interfaces
I also explained that without understanding the behavior of other classes and interfaces, it is not possible to fully understand the inner workings of the Graphics2D class.
Throughout this series of lessons, I have been providing you with information and sample programs designed to help you understand the various classes and interfaces that are necessary for an understanding of the Graphics2D class.
Two ways to achieve transparency
There are at least two different ways to achieve transparency in Java 2D. One approach is to use new constructors for the Color class that allow you to create solid colors with a specified degree of transparency. I will discuss that approach in this lesson.
A more general approach
A second, and possibly more general approach is to make use of an object that implements the Composite interface, passing a reference to that object to the setComposite() method of the Graphics2D class.
Earlier lessons explained the use of the Composite interface for solid colors as well as for color gradients
|A class to encapsulate colors in the default sRGB color space or colors in arbitrary color spaces identified by a ColorSpace. |
Every color has an implicit alpha value of 1.0 or an explicit one provided in the constructor. When constructing a Color with an explicit alpha or getting the color/alpha components of a Color, the color components are never premultiplied by the alpha component.
This class provides several overloaded constructors that allow you to provide an explicit alpha.
Sun's description of one of those constructors follows. This is the constructor that will be used in the sample program in this lesson.
|public Color( |
float r, float g,float b,float a)
Creates an sRGB color with the specified red, green, blue, and alpha values in the range (0.0 - 1.0). The actual color used in rendering will depend on finding the best match given the color space available for a given output device.
How is transparancy determined?
The value of alpha determines transparency with a value of 1.0f being opaque, and 0.0f being completely transparent.
A screen shot of the output
In case you are unable to compile and execute the program, a screen shot of the output follows. Note, however, that this screen shot was reduced to about seventy-percent of its original size in pixels, so some of the detail has been lost.
The GUI is a Frame object
The program draws a four-inch by four-inch Frame on the screen. It translates the origin to the center of the Frame. Then it draws a pair of X and Y-axes centered on the new origin.
A large circle
After drawing the X and Y-axes, the program draws a circle with a thick border centered on the origin. This circle is used later to provide visual cues relative to transparency.
After the large circle is drawn, three ellipses are drawn on top of one another in each quadrant. Each ellipse has a common center, and is rotated by sixty degrees relative to the ellipse beneath it. The color and transparency of each ellipse is established using the constructor described above.
Red on the bottom
A red ellipse is on the bottom of each stack and a blue ellipse is on the top of each stack. A green ellipse is sandwiched between the other two.
Different transparency values
The different ellipses are given various transparency values in the different quadrants to illustrate the effect of the alpha parameter of the setComposite() method.
An opaque border
Each ellipse is given an opaque border, which makes it easier to visually discern the stacking order of the transparent versions of the ellipses.
Transparency by quadrant
Here is the transparency given to each of the ellipses in the different quadrants.
All three ellipses are 30-percent transparent
None are opaque
Unlike previous lessons with similar sample programs, none of the ellipses are opaque in all four quadrants. As a result, the large black circle shows through all three ellipses in all quadrants except the upper-left quadrant.
All three ellipses are opaque in the upper-left quadrant, so nothing shows through.
Other ellipses become transparent
All three ellipses are made progressively more transparent as you move through the other three quadrants. As a result, you can see through all three ellipses. In other words, you can see the geometric figures that lie beneath them (the other ellipses and the large black circle).
Similar to previous lesson
The material in this lesson is very similar to previous lessons except for the use of the Color constructor as an alternate to the setComposite() method to achieve transparency. Therefore, I am not going to discuss the output of this program in detail.
Illustrates rotation and translation
As mentioned in the earlier lesson, this lesson also provides a good illustration of the benefits of rotation and translation. The task of rotating the ellipses relative to each other and the task of translating them into the various quadrants was made much easier (even possible) through the use of the AffineTransform to rotate and translate the ellipses.
The normal caveat regarding inches
|This discussion of dimensions in inches on the screen depends on the method named getScreenResolution() returning the correct value. However, the getScreenResolution() method always seems to return 120 on my computer regardless of the actual screen resolution settings.|
Will discuss in fragments
I will briefly discuss this program in fragments. The controlling class and the constructor for the GUI class are essentially the same as you have seen in several previous lessons, so, I won't repeat that discussion here. You can view that material in the complete listing of the program at the end of the lesson.
All of the interesting action takes place in the overridden paint() method, so I will begin the discussion there.
Overridden paint() method
The beginning portions of the overridden paint() method should be familiar to you by now as well. So, I am going to let the comments in Figure 1 speak for themselves.
Setting the Stroke
Figure 2 sets the Stroke to 0.05 inches. This will cause each ellipse drawn following this fragment to have a border of that width.
I discussed the use of setStroke() and BasicStroke in an earlier lesson, so I won't discuss it further here.
Figure 3 translates the origin to the center of what was previously the upper-left quadrant. After this statement is executed, any geometric figure that is drawn centered on the origin will actually be rendered in the center of what was previously the upper-left quadrant.
This should also be old stuff to you by now.
Opaque red-to-green ellipse outline
Figure 4 draws an opaque outline of a red ellipse using the Stroke object instantiated earlier. This ellipse is centered on the new origin.
The code has been covered in previous lessons, so I won't discuss it further here.
Fill the ellipse with an opaque solid red color
Figure 5 contains the material that is new to this lesson. This fragment instantiates a new Color object with an alpha value of 1.0f, which is the alpha value for opaque as described above.
The parameters to the constructor also specify that the color will be pure red with no contribution from either green or blue.
The fill() method is then used to fill the ellipse according to the new Color object that is passed to the setPaint() method before invoking fill(). Except for the use of the Color constructor that includes an alpha parameter, there is nothing new here.
Skip to upper-right quadrant
Because much of the code in this lesson is very similar to code that was explained in previous lessons, I am going to skip ahead to the code that establishes the fill colors and transparency values for the ellipses in the upper-right quadrant. (You can view all of the code in the complete listing of the program at the end of the lesson.)
Set fill color and transparency
In addition, for brevity, I am going to delete some of the code having to do with that quadrant. Figure 6 shows only the code required to establish the fill colors and transparency values for each of the ellipses in that quadrant.
Percent opaque versus percent transparent
You may prefer to think of the transparency specified by an alpha value of 0.7f as representing 70-percent opaque instead of 30-percent transparent.
Note that for solid colors, this approach is an alternative to the use of the setComposite() method of the Grapics2D class (along with the AlphaComposite class) to control the manner in which new pixel values are composited with existing pixel values.
Copyright 2000, R. G. Baldwin
About the author
Richard Baldwin is a college professor and private consultant whose primary focus is a combination of Java and XML. In addition to the many platform-independent benefits of Java applications, he believes that a combination of Java and XML will become the primary driving force in the delivery of structured information on the Web.
Richard has participated in numerous consulting projects involving Java, XML, or a combination of the two. He frequently provides onsite Java and/or XML training at the high-tech companies located in and around Austin, Texas. He is the author of Baldwin's Java Programming Tutorials, which has gained a worldwide following among experienced and aspiring Java programmers. He has also published articles on Java Programming in Java Pro magazine.
Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.