Added support for rendering label text with a shadow or bold text style.
Fixed MultiLineLabel.getPreferredSize() to attempt to lay out the label before obtaining its preferred size, and to lay out a dirtied label lazily rather than each time a setXXX() method is called. git-svn-id: https://samskivert.googlecode.com/svn/trunk@842 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: Label.java,v 1.18 2002/07/23 03:06:59 shaper Exp $
|
||||
// $Id: Label.java,v 1.19 2002/09/23 21:19:06 shaper Exp $
|
||||
//
|
||||
// samskivert library - useful routines for java programs
|
||||
// Copyright (C) 2002 Michael Bayne
|
||||
@@ -55,7 +55,7 @@ import com.samskivert.util.Tuple;
|
||||
* text at hand. It is not a component, but is intended for use by
|
||||
* components and other more heavyweight entities.
|
||||
*/
|
||||
public class Label implements SwingConstants
|
||||
public class Label implements SwingConstants, LabelStyleConstants
|
||||
{
|
||||
/**
|
||||
* Constructs a blank label.
|
||||
@@ -119,15 +119,14 @@ public class Label implements SwingConstants
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs the label to render the text outlined in the specified
|
||||
* Instructs the label to render the text with the specified alternate
|
||||
* color when rendering. The text itself will be rendered in whatever
|
||||
* color is currently set in the graphics context, but the outline
|
||||
* will always be in the specified color. Set the outline color to
|
||||
* <code>null</code> to disable outlining (which is the default).
|
||||
* color is currently set in the graphics context, but the outline or
|
||||
* shadow (if any) will always be in the specified color.
|
||||
*/
|
||||
public void setOutlineColor (Color color)
|
||||
public void setAlternateColor (Color color)
|
||||
{
|
||||
_outlineColor = color;
|
||||
_alternateColor = color;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,6 +148,15 @@ public class Label implements SwingConstants
|
||||
_align = align;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the style of the text within the label to one of the styles
|
||||
* defined in {@link LabelStyleConstants}.
|
||||
*/
|
||||
public void setStyle (int style)
|
||||
{
|
||||
_style = style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the target width for this label. Text will be wrapped to fit
|
||||
* into this width, forcibly breaking words on character boundaries if
|
||||
@@ -248,11 +256,26 @@ public class Label implements SwingConstants
|
||||
layouts.add(new Tuple(layout, bounds));
|
||||
}
|
||||
|
||||
// if we have an outline color, we need to be two pixels bigger in
|
||||
// both directions to account for stealthy, hack outline mode
|
||||
if (_outlineColor != null) {
|
||||
switch (_style) {
|
||||
case OUTLINE:
|
||||
// we need to be two pixels bigger in both directions
|
||||
_size.width += 2;
|
||||
_size.height += 2;
|
||||
break;
|
||||
|
||||
case SHADOW:
|
||||
// we need to be one pixel bigger in both directions
|
||||
_size.width += 1;
|
||||
_size.height += 1;
|
||||
break;
|
||||
|
||||
case BOLD:
|
||||
// we need to be one pixel bigger horizontally
|
||||
_size.width += 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// create our layouts array
|
||||
@@ -269,10 +292,10 @@ public class Label implements SwingConstants
|
||||
/**
|
||||
* Computes the lines of text for this label given the specified
|
||||
* target width. The overall size of the computed lines is stored into
|
||||
* the size parameter.
|
||||
* the <code>size</code> parameter.
|
||||
*
|
||||
* @return an ArrayList or null if keepWordsWhole was true and
|
||||
* the lines could not be layed out in the target width.
|
||||
* @return an {@link ArrayList} or null if <code>keepWordsWhole</code>
|
||||
* was true and the lines could not be layed out in the target width.
|
||||
*/
|
||||
protected ArrayList computeLines (
|
||||
LineBreakMeasurer measurer, int targetWidth, Dimension size,
|
||||
@@ -325,10 +348,27 @@ public class Label implements SwingConstants
|
||||
gfx.setColor(_textColor);
|
||||
}
|
||||
|
||||
// shift everything over and down by one pixel if we're outlining
|
||||
if (_outlineColor != null) {
|
||||
switch (_style) {
|
||||
case OUTLINE:
|
||||
// shift everything over and down by one pixel if we're outlining
|
||||
x += 1;
|
||||
y += 1;
|
||||
break;
|
||||
|
||||
case SHADOW:
|
||||
// shift everything over and up by one pixel if we're drawing
|
||||
// with a shadow
|
||||
x += 1;
|
||||
y -= 1;
|
||||
break;
|
||||
|
||||
case BOLD:
|
||||
// shift everything over one pixel if we're drawing in bold
|
||||
x -= 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// render our text
|
||||
@@ -338,10 +378,22 @@ public class Label implements SwingConstants
|
||||
y += layout.getAscent();
|
||||
|
||||
float dx = 0, extra = (float)(_size.width - lbounds.getWidth());
|
||||
// if we're outlining, we really have two pixels less space
|
||||
// than we think we do
|
||||
if (_outlineColor != null) {
|
||||
switch (_style) {
|
||||
case OUTLINE:
|
||||
// if we're outlining, we really have two pixels less space
|
||||
// than we think we do
|
||||
extra -= 2;
|
||||
break;
|
||||
|
||||
case SHADOW:
|
||||
case BOLD:
|
||||
// if we're rendering shadowed or bolded text, we really
|
||||
// have one pixel less space than we think we do
|
||||
extra -= 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (_align) {
|
||||
@@ -358,11 +410,12 @@ public class Label implements SwingConstants
|
||||
// "position" part of their bounds
|
||||
float rx = (float)(x + dx - lbounds.getX());
|
||||
|
||||
// render the outline using the hacky, but much nicer than
|
||||
// using "real" outlines (via TextLayout.getOutline), method
|
||||
if (_outlineColor != null) {
|
||||
switch (_style) {
|
||||
case OUTLINE:
|
||||
// render the outline using the hacky, but much nicer than
|
||||
// using "real" outlines (via TextLayout.getOutline), method
|
||||
Color textColor = gfx.getColor();
|
||||
gfx.setColor(_outlineColor);
|
||||
gfx.setColor(_alternateColor);
|
||||
layout.draw(gfx, rx - 1, y - 1);
|
||||
layout.draw(gfx, rx - 1, y);
|
||||
layout.draw(gfx, rx - 1, y + 1);
|
||||
@@ -372,6 +425,21 @@ public class Label implements SwingConstants
|
||||
layout.draw(gfx, rx + 1, y);
|
||||
layout.draw(gfx, rx + 1, y + 1);
|
||||
gfx.setColor(textColor);
|
||||
break;
|
||||
|
||||
case SHADOW:
|
||||
textColor = gfx.getColor();
|
||||
gfx.setColor(_alternateColor);
|
||||
layout.draw(gfx, rx - 1, y + 1);
|
||||
gfx.setColor(textColor);
|
||||
break;
|
||||
|
||||
case BOLD:
|
||||
layout.draw(gfx, rx + 1, y);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// and draw the text itself
|
||||
@@ -409,6 +477,9 @@ public class Label implements SwingConstants
|
||||
/** The text of the label. */
|
||||
protected String _text;
|
||||
|
||||
/** The text style. */
|
||||
protected int _style;
|
||||
|
||||
/** The text alignment. */
|
||||
protected int _align = -1; // -1 means default according to locale
|
||||
|
||||
@@ -428,9 +499,9 @@ public class Label implements SwingConstants
|
||||
/** Formatted text layout instances that contain each line of text. */
|
||||
protected Rectangle2D[] _lbounds;
|
||||
|
||||
/** The color in which to outline the text when rendering or null if
|
||||
* the text should not be outlined. */
|
||||
protected Color _outlineColor = null;
|
||||
/** The color in which to render the text outline or shadow if we're
|
||||
* rendering in outline or shadow mode. */
|
||||
protected Color _alternateColor = null;
|
||||
|
||||
/** The color in which to render the text or null if the text should
|
||||
* be rendered with the graphics context color. */
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// $Id: LabelStyleConstants.java,v 1.1 2002/09/23 21:19:06 shaper Exp $
|
||||
//
|
||||
// samskivert library - useful routines for java programs
|
||||
// Copyright (C) 2002 Walter Korman
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it
|
||||
// under the terms of the GNU Lesser General Public License as published
|
||||
// by the Free Software Foundation; either version 2.1 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
package com.samskivert.swing;
|
||||
|
||||
/**
|
||||
* Defines text style constants for use with the {@link Label} and {@link
|
||||
* MultiLineLabel}.
|
||||
*/
|
||||
public interface LabelStyleConstants
|
||||
{
|
||||
/** Constant denoting normal text style. */
|
||||
public static final int NORMAL = 0;
|
||||
|
||||
/** Constant denoting bold text style. */
|
||||
public static final int BOLD = 1;
|
||||
|
||||
/** Constant denoting outline text style. */
|
||||
public static final int OUTLINE = 2;
|
||||
|
||||
/** Constant denoting shadow text style. */
|
||||
public static final int SHADOW = 3;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: MultiLineLabel.java,v 1.2 2002/09/18 01:19:26 shaper Exp $
|
||||
// $Id: MultiLineLabel.java,v 1.3 2002/09/23 21:19:06 shaper Exp $
|
||||
//
|
||||
// samskivert library - useful routines for java programs
|
||||
// Copyright (C) 2002 Walter Korman
|
||||
@@ -30,12 +30,13 @@ import javax.swing.JComponent;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
import com.samskivert.Log;
|
||||
import com.samskivert.util.StringUtil;
|
||||
|
||||
/**
|
||||
* A Swing component that displays a {@link Label}.
|
||||
*/
|
||||
public class MultiLineLabel extends JComponent
|
||||
implements SwingConstants
|
||||
implements SwingConstants, LabelStyleConstants
|
||||
{
|
||||
/**
|
||||
* Constructs an empty multi line label.
|
||||
@@ -65,7 +66,7 @@ public class MultiLineLabel extends JComponent
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a multi line label that displays the supplied text and
|
||||
* Constructs a multi line label that displays the supplied text with
|
||||
* the specified constraints and alignment. Constraints should be one
|
||||
* of {@link #HORIZONTAL}, {@link #VERTICAL}, or <code>-1</code> if no
|
||||
* constraints are desired.
|
||||
@@ -84,6 +85,7 @@ public class MultiLineLabel extends JComponent
|
||||
public void setAntiAliased (boolean antialiased)
|
||||
{
|
||||
_antialiased = antialiased;
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,17 +94,16 @@ public class MultiLineLabel extends JComponent
|
||||
public void setText (String text)
|
||||
{
|
||||
_label.setText(text);
|
||||
dirty();
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the outline color used to display the label text if the text
|
||||
* style is currently set to outline mode.
|
||||
* Sets the alternate color used to display the label text.
|
||||
*/
|
||||
public void setOutlineColor (Color color)
|
||||
public void setAlternateColor (Color color)
|
||||
{
|
||||
_label.setOutlineColor(color);
|
||||
dirty();
|
||||
_label.setAlternateColor(color);
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,7 +112,7 @@ public class MultiLineLabel extends JComponent
|
||||
public void setAlignment (int align)
|
||||
{
|
||||
_label.setAlignment(align);
|
||||
dirty();
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,7 +121,16 @@ public class MultiLineLabel extends JComponent
|
||||
public void setOffAxisAlignment (int align)
|
||||
{
|
||||
_offalign = align;
|
||||
dirty();
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the text style used to render this label.
|
||||
*/
|
||||
public void setStyle (int style)
|
||||
{
|
||||
_label.setStyle(style);
|
||||
_dirty = true;
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
@@ -128,6 +138,11 @@ public class MultiLineLabel extends JComponent
|
||||
{
|
||||
super.paintComponent(g);
|
||||
|
||||
// if we're dirty, re-lay things out before painting ourselves
|
||||
if (_dirty) {
|
||||
layoutLabel();
|
||||
}
|
||||
|
||||
Graphics2D gfx = (Graphics2D)g;
|
||||
int align = _label.getAlignment();
|
||||
int dx = 0, dy = 0;
|
||||
@@ -154,11 +169,12 @@ public class MultiLineLabel extends JComponent
|
||||
public void doLayout ()
|
||||
{
|
||||
super.doLayout();
|
||||
|
||||
switch (_constrain) {
|
||||
case HORIZONTAL: _label.setTargetWidth(getWidth()); break;
|
||||
case VERTICAL: _label.setTargetHeight(getHeight()); break;
|
||||
}
|
||||
dirty();
|
||||
layoutLabel();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,7 +182,7 @@ public class MultiLineLabel extends JComponent
|
||||
* accordingly like to re-layout the label, update our component's
|
||||
* size, and repaint everything to suit.
|
||||
*/
|
||||
protected void dirty ()
|
||||
protected void layoutLabel ()
|
||||
{
|
||||
Graphics2D gfx = (Graphics2D)getGraphics();
|
||||
if (gfx != null) {
|
||||
@@ -178,15 +194,22 @@ public class MultiLineLabel extends JComponent
|
||||
_label.layout(gfx);
|
||||
gfx.dispose();
|
||||
|
||||
// update our size and force a layout and repaint
|
||||
// update our size and force a layout
|
||||
revalidate();
|
||||
repaint();
|
||||
|
||||
// note that we're no longer dirty
|
||||
_dirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
// documentation inherited
|
||||
public Dimension getPreferredSize ()
|
||||
{
|
||||
if (_dirty) {
|
||||
// attempt to lay out the label before obtaining its preferred
|
||||
// dimensions
|
||||
layoutLabel();
|
||||
}
|
||||
Dimension size = _label.getSize();
|
||||
return (size == null) ? new Dimension(10, 10) : size;
|
||||
}
|
||||
@@ -205,4 +228,7 @@ public class MultiLineLabel extends JComponent
|
||||
|
||||
/** Whether to render the label with anti-aliasing. */
|
||||
protected boolean _antialiased;
|
||||
|
||||
/** Whether this label is dirty and should be re-layed out. */
|
||||
protected boolean _dirty;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user