home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-03-18 | 12.8 KB | 459 lines |
- package symantec.itools.awt;
-
- import java.awt.Canvas;
- import java.awt.Graphics;
- import java.awt.FontMetrics;
- import java.awt.Dimension;
- import java.awt.Label;
- import java.beans.PropertyVetoException;
- import java.beans.PropertyChangeListener;
- import java.beans.VetoableChangeListener;
- import java.beans.PropertyChangeEvent;
- import symantec.itools.beans.VetoableChangeSupport;
- import symantec.itools.beans.PropertyChangeSupport;
-
- // 05/13/95 CAR Added resize and reshape methods.
- // 06/01/97 RKM Updated to support Java 1.1
- // 06/11/97 LAB Polished, and added listener registration functions.
- // 07/24/97 CAR marked fields transient as needed
-
- /**
- * This class implements a multiple-line text label.
- * It displays text on one or more lines, wrapping text
- * as needed to fit in the available horizontal space.
- *
- * @version 1.1, June 11, 1997
- *
- * @author Symantec
- */
- public class WrappingLabel extends Canvas implements AlignStyle
- {
- /**
- * Constructs a default wrapping label. Default values are an empty text string
- * and left alignment.
- */
- public WrappingLabel()
- {
- this("");
- }
-
- /**
- * Constructs a wrapping label that displays the specified string.
- * The label will default to left alignment.
- *
- * @param s string to be displayed in label
- */
- public WrappingLabel(String s)
- {
- this(s, WrappingLabel.ALIGN_LEFT);
- }
-
- /**
- * Constructs wrapping label with the specified text and alignment.
- *
- * @param s the string to be displayed in label
- * @param a the alignment, one of ALIGN_LEFT, ALIGN_CENTERED, or ALIGN_RIGHT
- *
- * @see symantec.itools.awt.AlignStyle
- * @see symantec.itools.awt.AlignStyle#ALIGN_LEFT
- * @see symantec.itools.awt.AlignStyle#ALIGN_CENTERED
- * @see symantec.itools.awt.AlignStyle#ALIGN_RIGHT
- */
- public WrappingLabel(String s, int a)
- {
- try
- {
- setText(s);
- }
- catch(PropertyVetoException veto) {};
-
- try
- {
- setAlignStyle(a);
- }
- catch(PropertyVetoException veto) {};
- }
-
-
- //--------------------------------------------------
- // accessor members
- //--------------------------------------------------
-
- /**
- * Gets the current text alignment setting.
- *
- * @return the current alignment, one of ALIGN_LEFT, ALIGN_CENTERED, or ALIGN_RIGHT
- * @see #setAlignStyle
- * @see symantec.itools.awt.AlignStyle
- * @see symantec.itools.awt.AlignStyle#ALIGN_LEFT
- * @see symantec.itools.awt.AlignStyle#ALIGN_CENTERED
- * @see symantec.itools.awt.AlignStyle#ALIGN_RIGHT
- */
- public int getAlignStyle()
- {
- return align;
- }
-
- /**
- * Sets the text alignment.
- *
- * @param newAlignStyle the new alignment style, one of ALIGN_LEFT, ALIGN_CENTERED, or ALIGN_RIGHT
- * @see #getAlignStyle
- * @see symantec.itools.awt.AlignStyle
- * @see symantec.itools.awt.AlignStyle#ALIGN_LEFT
- * @see symantec.itools.awt.AlignStyle#ALIGN_CENTERED
- * @see symantec.itools.awt.AlignStyle#ALIGN_RIGHT
- * @exception PropertyVetoException
- * if the specified property value is unacceptable
- */
- public void setAlignStyle(int newAlignStyle)
- throws PropertyVetoException
- {
- if (align != newAlignStyle)
- {
- Integer oldAlignStyleInt = new Integer(align);
- Integer newAlignStyleInt = new Integer(newAlignStyle);
-
- vetos.fireVetoableChange("AlignStyle",oldAlignStyleInt,newAlignStyleInt);
-
- align = newAlignStyle;
-
- changes.firePropertyChange("AlignStyle",oldAlignStyleInt,newAlignStyleInt);
-
- repaint();
- }
- }
-
- /**
- * Gets the current label text.
- *
- * @return the label's text string
- * @see #setText
- */
- public String getText()
- {
- return text;
- }
-
- /**
- * Sets the label text.
- *
- * @param s the new label text
- *
- * @see #getText
- * @exception PropertyVetoException
- * if the specified property value is unacceptable
- */
- public void setText(String newText)
- throws PropertyVetoException
- {
- if (!symantec.itools.util.GeneralUtils.objectsEqual(text,newText))
- {
- String oldText = text;
-
- vetos.fireVetoableChange("Text",oldText,newText);
-
- text = newText;
-
- changes.firePropertyChange("Text",oldText,newText);
-
- repaint();
- }
- }
-
- //--------------------------------------------------
- // event methods
- //--------------------------------------------------
-
-
- //--------------------------------------------------
- // class methods
- //--------------------------------------------------
-
-
- //--------------------------------------------------
- // member methods
- //--------------------------------------------------
-
- /**
- * Returns an empty string.
- * This is a standard Java AWT method which typically returns a string
- * representing the state of this object.
- *
- * @return the empty string
- */
- public String paramString()
- {
- return "";
- }
-
- /**
- * Moves and/or resizes this component.
- * This is a standard Java AWT method which gets called to move and/or
- * resize this component. Components that are in containers with layout
- * managers should not call this method, but rely on the layout manager
- * instead.
- *
- * It is overridden here to re-wrap the text as necessary.
- *
- * @param x horizontal position in the parent's coordinate space
- * @param y vertical position in the parent's coordinate space
- * @param width the new width
- * @param height the new height
- */
- public synchronized void reshape(int x, int y, int width, int height) {
- super.reshape(x, y, width, height);
- invalidate();
- validate();
- repaint();
- }
-
- /**
- * Resizes this component.
- * This is a standard Java AWT method which gets called to
- * resize this component. Components that are in containers with layout
- * managers should not call this method, but rely on the layout manager
- * instead.
- *
- * It is overridden here to re-wrap the text as necessary.
- *
- * @param width the new width, in pixels
- * @param height the new height, in pixels
- */
- public synchronized void resize(int width, int height) {
- super.resize(width, height);
- invalidate();
- validate();
- repaint();
- }
-
- /**
- * Paints this component using the given graphics context.
- * This is a standard Java AWT method which typically gets called
- * by the AWT to handle painting this component. It paints this component
- * using the given graphics context. The graphics context clipping region
- * is set to the bounding rectangle of this component and its [0,0]
- * coordinate is this component's top-left corner.
- *
- * @param g the graphics context used for painting
- * @see java.awt.Component#repaint
- * @see java.awt.Component#update
- */
- public void paint(Graphics g)
- {
- if (text != null)
- {
- int x, y;
- int boundx, boundy;
- Dimension d;
- int fromIndex = 0;
- int pos = 0;
- int bestpos;
- String largestString;
- String s;
-
- // Set up some class variables
- fm = getToolkit().getFontMetrics(getFont());
- baseline = fm.getMaxAscent();
-
- // Get the maximum height and width of the current control
- d = size();
- boundx = d.width;
- boundy = d.height;
-
- // X and Y represent the coordinates of the upper left portion
- // of the next text line.
- x = 0;
- y = 0;
-
- // While we haven't passed the bottom of the label and we
- // haven't run past the end of the string...
- while ((y + fm.getHeight()) <= boundy && fromIndex != -1)
- {
- // Automatically skip any spaces at the beginning of the line
- while (fromIndex < text.length() && text.charAt(fromIndex) == ' ')
- {
- ++fromIndex;
- // If we hit the end of line while skipping spaces, we're done.
- if (fromIndex >= text.length()) break;
- }
-
- // fromIndex represents the beginning of the line
- pos = fromIndex;
- bestpos = -1;
- largestString = null;
-
- while (pos >= fromIndex)
- {
- pos = text.indexOf(' ', pos);
-
- // Couldn't find another space?
- if (pos == -1)
- {
- s = text.substring(fromIndex);
- }
- else
- {
- s = text.substring(fromIndex, pos);
- }
-
- // If the string fits, keep track of it.
- if (fm.stringWidth(s) < boundx)
- {
- largestString = s;
- bestpos = pos;
-
- // If we've hit the end of the string, use it.
- if (pos == -1) break;
- }
- else
- {
- break;
- }
-
- ++pos;
- }
-
- if (largestString == null)
- {
- // Couldn't wrap at a space, so find the largest line
- // that fits and print that. Note that this will be
- // slightly off -- the width of a string will not necessarily
- // be the sum of the width of its characters, due to kerning.
- int totalWidth = 0;
- int oneCharWidth = 0;
-
- pos = fromIndex;
-
- while (pos < text.length())
- {
- oneCharWidth = fm.charWidth(text.charAt(pos));
- if ((totalWidth + oneCharWidth) >= boundx) break;
- totalWidth += oneCharWidth;
- ++pos;
- }
-
- drawAlignedString(g, text.substring(fromIndex, pos), x, y, boundx);
- fromIndex = pos;
- }
- else
- {
- drawAlignedString(g, largestString, x, y, boundx);
-
- fromIndex = bestpos;
- }
-
- y += fm.getHeight();
- }
-
- // We're done with the font metrics...
- fm = null;
- }
- }
-
- /**
- * Adds a listener for all event changes.
- * @param PropertyChangeListener listener the listener to add.
- * @see #removePropertyChangeListener
- */
- public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
- {
- changes.addPropertyChangeListener(listener);
- }
-
- /**
- * Removes a listener for all event changes.
- * @param PropertyChangeListener listener the listener to remove.
- * @see #addPropertyChangeListener
- */
- public synchronized void removePropertyChangeListener(PropertyChangeListener listener)
- {
- changes.removePropertyChangeListener(listener);
- }
-
- /**
- * Adds a vetoable listener for all event changes.
- * @param VetoableChangeListener listener the listener to add.
- * @see #removeVetoableChangeListener
- */
- public synchronized void addVetoableChangeListener(VetoableChangeListener listener)
- {
- vetos.addVetoableChangeListener(listener);
- }
-
- /**
- * Removes a vetoable listener for all event changes.
- * @param VetoableChangeListener listener the listener to remove.
- * @see #addVetoableChangeListener
- */
- public synchronized void removeVetoableChangeListener(VetoableChangeListener listener)
- {
- vetos.removeVetoableChangeListener(listener);
- }
-
- /**
- * This helper method draws a string aligned the requested way.
- * @param g the graphics context used for painting
- * @param s the string to draw
- * @param x the point to start drawing from, x coordinate
- * @param y the point to start drawing from, y coordinate
- * @param width the width of the area to draw in, in pixels
- */
- protected void drawAlignedString(Graphics g, String s, int x, int y, int width)
- {
- int drawx;
- int drawy;
-
- drawx = x;
- drawy = y + baseline;
-
- if (align != WrappingLabel.ALIGN_LEFT)
- {
- int sw;
-
- sw = fm.stringWidth(s);
-
- if (align == WrappingLabel.ALIGN_CENTERED)
- {
- drawx += (width - sw) / 2;
- }
- else if (align == WrappingLabel.ALIGN_RIGHT)
- {
- drawx = drawx + width - sw;
- }
- }
-
- g.drawString(s, drawx, drawy);
- }
-
- /**
- * The text string being displayed.
- */
- protected String text;
-
- /**
- * The current text alignment.
- * One of ALIGN_LEFT, ALIGN_CENTERED, or ALIGN_RIGHT.
- * @see symantec.itools.awt.AlignStyle
- * @see symantec.itools.awt.AlignStyle#ALIGN_LEFT
- * @see symantec.itools.awt.AlignStyle#ALIGN_CENTERED
- * @see symantec.itools.awt.AlignStyle#ALIGN_RIGHT
- */
- protected int align;
-
- /**
- * The maximum ascent of the font used to display text.
- *
- */
- protected int baseline;
-
- /**
- * The metrics of the font used to display text.
- */
- transient protected FontMetrics fm;
-
- private symantec.itools.beans.VetoableChangeSupport vetos = new symantec.itools.beans.VetoableChangeSupport(this);
- private symantec.itools.beans.PropertyChangeSupport changes = new symantec.itools.beans.PropertyChangeSupport(this);
- }
-
-