Java Reference
In-Depth Information
import java.awt.image.BufferedImage;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
You could have implemented two separate helper methods for setting up the CUSTOM16 and CUSTOM24
icons, but there's quite a lot of common code so I made it one method. The first step is to obtain the
BufferedImage object that the icon argument contains. The getImage() method returns a reference of type
Image , so you need to cast it to the proper type. The getWidth() method for image returns the width of the
image, which in this particular case is the same as the height. There's a getHeight() method for when they
differ. You want to draw a filled rectangle indented from the boundaries of the image, but the indents need
to be different for the 16 ×16 and 24 ×24 images so that the menu item and toolbar button appear similar to
the others in the same set.
The createGraphics() method returns a Graphics2D object that you can use to draw on the image. In
both cases you draw a filled rectangle in the color specified by the second argument. The differences for the
two sizes of image are the dimensions of the rectangle and the position of its top-left corner.
For a 24 ×24 image that is used on a toolbar button, you draw a capital 'C' for “Custom" centrally on
the image to distinguish the custom color toolbar button from those that are used to set the standard colors.
To determine the position for the text on the image, you create a java.awt.font.TextLayout object that
provides information about styled text. In this case the text is just a single character "C" that you pass to the
TextLayout constructor. The second argument is the font used to draw the text and the third argument is a
FontRenderContext object that encapsulates the context in which the text is rendered, and you obtain both
by calling methods for g2D . The TextLayout object needs all this information to determine the layout of the
text. The getBounds() method for textLayout returns a rectangle that encloses the text. You use the height
and width of this rectangle in conjunction with the width of the filled rectangle to determine the position
where the text is to be drawn. Finally the drawString() method draws "C" on the image.
Note how the color for drawing the text is set. If you were to use a fixed color, the user might choose
the same color as a custom color, in which case the text would be invisible. To contrast the text with the
background, you subtract the RGB values for the filled rectangle color from 255 and use these to create a
new Color object for the text. The only instance in which this won't produce a contrasting color is if the
RGB component values are all 128, but this color is an unlikely shade of mid-gray anyway. If you want to
take care of this, you could check for these RGB values, and use Color.BLACK for the text in this case.
Displaying the Color Chooser Dialog
Add a field to SketcherFrame to hold the current custom color:
private Color customColor = DEFAULT_ELEMENT_COLOR;
// Current custom color
It is initialized with the default color at the outset. This needs to be a field that is independent of elementCo-
lor because you want to remember the last custom color that was chosen, even when the element color is
changed to one of the standard colors.
Events from the custom color menu items and toolbar button are handled by the actionPerformed()
member of the ColorAction class.
Search WWH ::




Custom Search