8
|
Chapter 1, Basic JComponents
#2 Don’t Settle for Boring Text Labels
HACK
With the addition of this code to ImageTest’s main( ) method, the image-
based showcase program is complete. Figure 1-7 shows what the running
program looks like in the selected but disabled state.
H A C K
#2
Don’t Settle for Boring Text Labels Hack #2
JLabel is a Swing staple; but it’s easy to spruce up boring labels with drop
shadows, outlines, and even 3D text.
When you want to draw non-editable text, Swing provides only the JLabel.
You can change the font, size, color, and even add an icon. By using HTML
in your components
[Hack #52], you can even add things like underline and
bullets. This is fine for most jobs, but sometimes you need more. What if
you want a drop shadow or an embossed effect? The
JLabel is simply inade-
quate for richer interfaces. Fortunately, the Swing Team made it very easy to
extend the
JLabel and add these features yourself.
A great many text effects can be achieved with two simple features. First,
you can draw text multiple times, with each iteration slightly offset or in a
different color, to create effects like drop shadows and embossing. Second,
you can adjust the spacing between letters in a word (a feature known as
tracking in text-processing circles). Tracking is always specified in addition
to the default tracking specified by a font. Thus, a tracking of +1 would be
drawn as one extra pixel between each letter. A tracking of 0 would have the
same spacing as no extra tracking at all.
To implement all of this, you must override both the sizing and the painting
code in
JLabel, which of course calls for a subclass; see Example 1-5 for
details.
Figure 1-7. Selected and disabled
Don’t Settle for Boring Text Labels #2
Chapter 1, Basic JComponents
|
9
HACK
RichJLabel extends the standard javax.swing.JLabel and adds a tracking
argument to the constructor. Next, it adds two methods for the right and
left shadow. These are called shadows because they will be drawn below the
main text, but whether they actually look like shadows depends on the
color, as well as the x- and y-offsets passed into each method.
With the boilerplate out of the way, you need to handle sizing issues. The
JLabel automatically tells layout managers its preferred size based on the
font size. When you add custom tracking, this sizing would be incorrect,
resulting in labels too small for the text they contain. For small font sizes it
won’t be noticeable, but with large fancy text and cool effects—and we all
want cool effects—it could chop off half of a letter or more.
Every Swing component returns its desired size using the
getPreferredSize( )
method. By adjusting the returned size to be a bit bigger, layout controls
using this component will give the label the extra room it needs:
public Dimension getPreferredSize( ) {
String text = getText( );
FontMetrics fm = this.getFontMetrics(getFont( ));
int w = fm.stringWidth(text);
w += (text.length( )-1)*tracking;
w += left_x + right_x;
Example 1-5. Defining a richer JLabel
public class RichJLabel extends JLabel {
private int tracking;
public RichJLabel(String text, int tracking) {
super(text);
this.tracking = tracking;
}
private int left_x, left_y, right_x, right_y;
private Color left_color, right_color;
public void setLeftShadow(int x, int y, Color color) {
left_x = x;
left_y = y;
left_color = color;
}
public void setRightShadow(int x, int y, Color color) {
right_x = x;
right_y = y;
right_color = color;
}

Get Swing Hacks now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.