| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2006 IBM Corporation and others. |
| // All rights reserved. This program and the accompanying materials |
| // are made available under the terms of the Eclipse Public License v1.0 |
| // which accompanies this distribution, and is available at |
| // http://www.eclipse.org/legal/epl-v10.html |
| // |
| // Contributors: |
| // IBM Corporation - initial implementation |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.authoring.gef.figures; |
| |
| import org.eclipse.draw2d.ColorConstants; |
| import org.eclipse.draw2d.Figure; |
| import org.eclipse.draw2d.FigureUtilities; |
| import org.eclipse.draw2d.Graphics; |
| import org.eclipse.draw2d.IFigure; |
| import org.eclipse.draw2d.PositionConstants; |
| import org.eclipse.draw2d.geometry.Dimension; |
| import org.eclipse.draw2d.geometry.Insets; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.graphics.FontMetrics; |
| import org.eclipse.swt.graphics.Image; |
| |
| import com.ibm.icu.text.BreakIterator; |
| import com.ibm.icu.util.StringTokenizer; |
| |
| /** |
| * Provides support for text wrap in a label. |
| * |
| * @author Shashidhar Kannoori |
| * @since 1.0 |
| * |
| */ |
| public class WrappableLabel extends Figure implements PositionConstants { |
| |
| private static String ELLIPSIS = "..."; //$NON-NLS-1$ |
| |
| private Image icon; |
| |
| private String text = ""; //$NON-NLS-1$ |
| |
| private String subStringText; |
| |
| private Dimension textSize; |
| |
| private Dimension subStringTextSize; |
| |
| private Dimension iconSize = new Dimension(0, 0); |
| |
| private Point iconLocation; |
| |
| private Point textLocation; |
| |
| private int textAlignment = CENTER; |
| |
| private int iconAlignment = CENTER; |
| |
| private int labelAlignment = CENTER; |
| |
| private int textPlacement = SOUTH; |
| |
| private int iconTextGap = 3; |
| |
| private static final int FLAG_SELECTED = MAX_FLAG << 1, |
| FLAG_HASFOCUS = MAX_FLAG << 2, FLAG_WRAP = MAX_FLAG << 5, |
| FLAG_WRAP_ALIGN = MAX_FLAG << 6; |
| |
| // The primary dimensions used to calculate text size. |
| private Dimension textDimension = new Dimension(-1, -1); |
| |
| private Dimension prefSizeDimension = new Dimension(-1, -1); |
| |
| private int wrapWidth; |
| |
| public WrappableLabel() { |
| super(); |
| } |
| |
| /** |
| * Construct a Label with passed String as its text. |
| * |
| * @param s |
| * the label text |
| * @since 2.0 |
| */ |
| public WrappableLabel(String s) { |
| setText(s); |
| } |
| |
| /** |
| * Construct a WrappedLabel with passed Image as its icon. |
| * |
| * @param i |
| * the WrappedLabel image |
| * @since 2.0 |
| */ |
| public WrappableLabel(Image i) { |
| setIcon(i); |
| } |
| |
| /** |
| * Construct a WrappedLabel with passed String as text and passed Image as |
| * its icon. |
| * |
| * @param s |
| * the WrappedLabel text |
| * @param i |
| * the WrappedLabel image |
| * @since 2.0 |
| */ |
| public WrappableLabel(String s, Image i) { |
| setText(s); |
| setIcon(i); |
| } |
| |
| private void alignOnHeight(Point loc, Dimension size, int alignment) { |
| Insets insets = getInsets(); |
| switch (alignment) { |
| case TOP: |
| loc.y = insets.top; |
| break; |
| case BOTTOM: |
| loc.y = bounds.height - size.height - insets.bottom; |
| break; |
| default: |
| loc.y = (bounds.height - size.height) / 2; |
| } |
| } |
| |
| private void alignOnWidth(Point loc, Dimension size, int alignment) { |
| Insets insets = getInsets(); |
| switch (alignment) { |
| case LEFT: |
| loc.x = insets.left; |
| break; |
| case RIGHT: |
| loc.x = bounds.width - size.width - insets.right; |
| break; |
| default: |
| loc.x = (bounds.width - size.width) / 2; |
| } |
| } |
| |
| private void calculateAlignment() { |
| switch (textPlacement) { |
| case EAST: |
| case WEST: |
| alignOnHeight(textLocation, getTextSize(), textAlignment); |
| alignOnHeight(iconLocation, iconSize, iconAlignment); |
| break; |
| case NORTH: |
| case SOUTH: |
| alignOnWidth(textLocation, getSubStringTextSize(), textAlignment); |
| alignOnWidth(iconLocation, iconSize, iconAlignment); |
| break; |
| } |
| } |
| |
| /** |
| * Calculates the size of the WrappedLabel using the passed Dimension as the |
| * size of the WrappedLabel's text. |
| * |
| * @param txtSize |
| * the precalculated size of the WrappedLabel's text |
| * @return the WrappedLabel's size |
| * @since 2.0 |
| */ |
| protected Dimension calculateLabelSize(Dimension txtSize) { |
| int gap = iconTextGap; |
| if (getIcon() == null || getText().equals("")) //$NON-NLS-1$ |
| gap = 0; |
| Dimension d = new Dimension(0, 0); |
| if (textPlacement == WEST || textPlacement == EAST) { |
| d.width = iconSize.width + gap + txtSize.width; |
| d.height = Math.max(iconSize.height, txtSize.height); |
| } else { |
| d.width = Math.max(iconSize.width, txtSize.width); |
| d.height = iconSize.height + gap + txtSize.height; |
| } |
| return d; |
| } |
| |
| private void calculateLocations() { |
| textLocation = new Point(); |
| iconLocation = new Point(); |
| |
| calculatePlacement(); |
| calculateAlignment(); |
| Dimension offset = getSize().getDifference(getPreferredSize()); |
| offset.width += getTextSize().width - getSubStringTextSize().width; |
| switch (labelAlignment) { |
| case CENTER: |
| offset.scale(0.5f); |
| break; |
| case LEFT: |
| offset.scale(0.0f); |
| break; |
| case RIGHT: |
| offset.scale(1.0f); |
| break; |
| case TOP: |
| offset.height = 0; |
| offset.scale(0.5f); |
| break; |
| case BOTTOM: |
| offset.height = offset.height * 2; |
| offset.scale(0.5f); |
| break; |
| default: |
| offset.scale(0.5f); |
| break; |
| } |
| |
| switch (textPlacement) { |
| case EAST: |
| case WEST: |
| offset.height = 0; |
| break; |
| case NORTH: |
| case SOUTH: |
| offset.width = 0; |
| break; |
| } |
| |
| textLocation.translate(offset); |
| iconLocation.translate(offset); |
| } |
| |
| private void calculatePlacement() { |
| int gap = iconTextGap; |
| if (icon == null || text.equals("")) //$NON-NLS-1$ |
| gap = 0; |
| Insets insets = getInsets(); |
| |
| switch (textPlacement) { |
| case EAST: |
| iconLocation.x = insets.left; |
| textLocation.x = iconSize.width + gap + insets.left; |
| break; |
| case WEST: |
| textLocation.x = insets.left; |
| iconLocation.x = getSubStringTextSize().width + gap + insets.left; |
| break; |
| case NORTH: |
| textLocation.y = insets.top; |
| iconLocation.y = getTextSize().height + gap + insets.top; |
| break; |
| case SOUTH: |
| textLocation.y = iconSize.height + gap + insets.top; |
| iconLocation.y = insets.top; |
| } |
| } |
| |
| /** |
| * Calculates the size of the Label's text size. The text size calculated |
| * takes into consideration if the Label's text is currently truncated. If |
| * text size without considering current truncation is desired, use |
| * {@link #calculateTextSize()}. |
| * |
| * @return the size of the label's text, taking into account truncation |
| * @since 2.0 |
| */ |
| protected Dimension calculateSubStringTextSize() { |
| return FigureUtilities.getTextExtents(getSubStringText(), getFont()); |
| } |
| |
| /** |
| * Calculates and returns the size of the Label's text. Note that this |
| * Dimension is calculated using the Label's full text, regardless of |
| * whether or not its text is currently truncated. If text size considering |
| * current truncation is desired, use {@link #calculateSubStringTextSize()}. |
| * |
| * @return the size of the label's text, ignoring truncation |
| * @since 2.0 |
| */ |
| protected Dimension calculateTextSize() { |
| // return FigureUtilities.getTextExtents(getText(), getFont()); |
| return FigureUtilities.getTextExtents(getWrappedText(getSize().width, |
| getSize().height), getFont()); |
| |
| } |
| |
| private void clearLocations() { |
| iconLocation = textLocation = null; |
| } |
| |
| /** |
| * Returns the Label's icon. |
| * |
| * @return the label icon |
| * @since 2.0 |
| */ |
| public Image getIcon() { |
| return icon; |
| } |
| |
| /** |
| * Returns the current alignment of the Label's icon. The default is |
| * {@link PositionConstants#CENTER}. |
| * |
| * @return the icon alignment |
| * @since 2.0 |
| */ |
| public int getIconAlignment() { |
| return iconAlignment; |
| } |
| |
| /** |
| * Returns the bounds of the Label's icon. |
| * |
| * @return the icon's bounds |
| * @since 2.0 |
| */ |
| public Rectangle getIconBounds() { |
| Rectangle bounds = getBounds(); |
| return new Rectangle(bounds.getLocation().translate(getIconLocation()), |
| iconSize); |
| } |
| |
| /** |
| * Returns the location of the Label's icon relative to the Label. |
| * |
| * @return the icon's location |
| * @since 2.0 |
| */ |
| protected Point getIconLocation() { |
| if (iconLocation == null) |
| calculateLocations(); |
| return iconLocation; |
| } |
| |
| /** |
| * Returns the gap in pixels between the Label's icon and its text. |
| * |
| * @return the gap |
| * @since 2.0 |
| */ |
| public int getIconTextGap() { |
| return iconTextGap; |
| } |
| |
| /** |
| * @see IFigure#getMinimumSize(int, int) |
| */ |
| public Dimension getMinimumSize(int w, int h) { |
| if (minSize != null) |
| return minSize; |
| minSize = new Dimension(); |
| if (getLayoutManager() != null) |
| minSize.setSize(getLayoutManager().getMinimumSize(this, w, h)); |
| |
| Dimension labelSize = calculateLabelSize(FigureUtilities |
| .getTextExtents(ELLIPSIS, getFont()).intersect( |
| FigureUtilities.getTextExtents(getText(), getFont()))); |
| Insets insets = getInsets(); |
| labelSize.expand(insets.getWidth(), insets.getHeight()); |
| minSize.union(labelSize); |
| return minSize; |
| } |
| |
| /** |
| * @see IFigure#getPreferredSize(int, int) |
| */ |
| public Dimension getPreferredSize(int wHint, int hHint) { |
| if (prefSize == null || wHint != prefSizeDimension.width |
| || hHint != prefSizeDimension.height) { |
| prefSize = calculateLabelSize(getTextSize(wHint, hHint)); |
| Insets insets = getInsets(); |
| prefSize.expand(insets.getWidth(), insets.getHeight()); |
| if (getLayoutManager() != null) |
| prefSize.union(getLayoutManager().getPreferredSize(this, wHint, |
| hHint)); |
| } |
| if (wHint >= 0 && wHint < prefSize.width) { |
| Dimension minSize = getMinimumSize(wHint, hHint); |
| Dimension result = prefSize.getCopy(); |
| result.width = Math.min(result.width, wHint); |
| result.width = Math.max(minSize.width, result.width); |
| prefSizeDimension.width = result.width; |
| prefSizeDimension.height = result.width; |
| return result; |
| } |
| return prefSize; |
| } |
| |
| /** |
| * Calculates the amount of the Label's current text will fit in the Label, |
| * including an elipsis "..." if truncation is required. |
| * |
| * @return the substring |
| * @since 2.0 |
| */ |
| public String getSubStringText() { |
| if (subStringText != null) |
| return subStringText; |
| |
| subStringText = text; |
| Dimension shrink = getPreferredSize(getSize().width, getSize().height) |
| .getDifference(getSize()); |
| Dimension effectiveSize = getTextSize().getExpanded(-shrink.width, |
| -shrink.height); |
| Font currentFont = getFont(); |
| int fontHeight = FigureUtilities.getFontMetrics(currentFont) |
| .getHeight(); |
| int maxLines = (int) (effectiveSize.height / (double) fontHeight); |
| |
| StringBuffer accumlatedText = new StringBuffer(); |
| StringBuffer remainingText = new StringBuffer(getText()); |
| int i = 0, j = 0; |
| |
| while (remainingText.length() > 0 && j++ < maxLines) { |
| i = getLineWrapPosition(remainingText.toString(), currentFont, |
| effectiveSize.width); |
| |
| if (accumlatedText.length() > 0) |
| accumlatedText.append("\n"); //$NON-NLS-1$ |
| |
| if (i == 0 || (remainingText.length() > i && j == maxLines)) { |
| int dotsWidth = FigureUtilities.getTextExtents(ELLIPSIS, |
| currentFont).width; |
| i = getLargestSubstringConfinedTo(remainingText.toString(), |
| currentFont, Math.max(effectiveSize.width - dotsWidth, |
| 0)); |
| accumlatedText.append(remainingText.substring(0, i)); |
| accumlatedText.append(ELLIPSIS); |
| } else |
| accumlatedText.append(remainingText.substring(0, i)); |
| remainingText.delete(0, i); |
| } |
| return subStringText = accumlatedText.toString(); |
| } |
| |
| /** |
| * Returns the size of the Label's current text. If the text is currently |
| * truncated, the truncated text with its ellipsis is used to calculate the |
| * size. |
| * |
| * @return the size of this label's text, taking into account truncation |
| * @since 2.0 |
| */ |
| protected Dimension getSubStringTextSize() { |
| if (subStringTextSize == null) |
| subStringTextSize = calculateSubStringTextSize(); |
| return subStringTextSize; |
| } |
| |
| /** |
| * Returns the text of the label. Note that this is the complete text of the |
| * label, regardless of whether it is currently being truncated. Call |
| * {@link #getSubStringText()} to return the label's current text contents |
| * with truncation considered. |
| * |
| * @return the complete text of this label |
| * @since 2.0 |
| */ |
| public String getText() { |
| return text; |
| } |
| |
| /** |
| * Returns the current alignment of the Label's text. The default text |
| * alignment is {@link PositionConstants#CENTER}. |
| * |
| * @return the text alignment |
| */ |
| public int getTextAlignment() { |
| return textAlignment; |
| } |
| |
| /** |
| * Returns the bounds of the label's text. Note that the bounds are |
| * calculated using the label's complete text regardless of whether the |
| * label's text is currently truncated. |
| * |
| * @return the bounds of this label's complete text |
| * @since 2.0 |
| */ |
| public Rectangle getTextBounds() { |
| Rectangle bounds = getBounds(); |
| return new Rectangle(bounds.getLocation().translate(getTextLocation()), |
| textSize); |
| } |
| |
| /** |
| * Returns the location of the label's text relative to the label. |
| * |
| * @return the text location |
| * @since 2.0 |
| */ |
| protected Point getTextLocation() { |
| if (textLocation != null) |
| return textLocation; |
| calculateLocations(); |
| return textLocation; |
| } |
| |
| /** |
| * Returns the current placement of the label's text relative to its icon. |
| * The default text placement is {@link PositionConstants#EAST}. |
| * |
| * @return the text placement |
| * @since 2.0 |
| */ |
| public int getTextPlacement() { |
| return textPlacement; |
| } |
| |
| /** |
| * Returns the size of the label's complete text. Note that the text used to |
| * make this calculation is the label's full text, regardless of whether the |
| * label's text is currently being truncated and is displaying an ellipsis. |
| * If the size considering current truncation is desired, call |
| * {@link #getSubStringTextSize()}. |
| * |
| * @return the size of this label's complete text |
| * @since 2.0 |
| */ |
| protected Dimension getTextSize() { |
| if (textSize == null) |
| textSize = calculateTextSize(); |
| return textSize; |
| } |
| |
| /** |
| * Returns the size of the label's complete text. Note that the text used to |
| * make this calculation is the label's full text, regardless of whether the |
| * label's text is currently being truncated and is displaying an ellipsis. |
| * If the size considering current truncation is desired, call |
| * {@link #getSubStringTextSize()}. |
| * |
| * @return the size of this label's complete text |
| * @since 2.0 |
| */ |
| protected Dimension getTextSize(int width, int height) { |
| if (textSize == null) { |
| textSize = calculateTextSize(width, height); |
| textDimension.width = width; |
| textDimension.height = height; |
| } |
| return textSize; |
| } |
| |
| /** |
| * @see IFigure#invalidate() |
| */ |
| public void invalidate() { |
| prefSize = null; |
| minSize = null; |
| clearLocations(); |
| textSize = null; |
| subStringTextSize = null; |
| subStringText = null; |
| super.invalidate(); |
| } |
| |
| /** |
| * Returns <code>true</code> if the label's text is currently truncated |
| * and is displaying an ellipsis, <code>false</code> otherwise. |
| * |
| * @return <code>true</code> if the label's text is truncated |
| * @since 2.0 |
| */ |
| public boolean isTextTruncated() { |
| return !getSubStringTextSize().equals(getTextSize()); |
| } |
| |
| /** |
| * @see Figure#paintFigure(Graphics) |
| */ |
| protected void paintFigure(Graphics graphics) { |
| if (isSelected()) { |
| graphics.pushState(); |
| graphics.setBackgroundColor(ColorConstants.menuBackgroundSelected); |
| graphics.fillRectangle(getSelectionRectangle()); |
| graphics.popState(); |
| graphics.setForegroundColor(ColorConstants.white); |
| } |
| if (hasFocus()) { |
| graphics.pushState(); |
| graphics.setXORMode(true); |
| graphics.setForegroundColor(ColorConstants.menuBackgroundSelected); |
| graphics.setBackgroundColor(ColorConstants.white); |
| graphics.drawFocus(getSelectionRectangle().resize(-1, -1)); |
| graphics.popState(); |
| } |
| if (isOpaque()) |
| super.paintFigure(graphics); |
| Rectangle bounds = getBounds(); |
| graphics.translate(bounds.x, bounds.y); |
| if (icon != null) |
| graphics.drawImage(icon, getIconLocation()); |
| |
| if (!isEnabled()) { |
| graphics.translate(1, 1); |
| graphics.setForegroundColor(ColorConstants.buttonLightest); |
| graphicsdrawText(graphics); |
| graphics.drawText(getSubStringText(), getTextLocation()); |
| graphics.translate(-1, -1); |
| graphics.setForegroundColor(ColorConstants.buttonDarker); |
| } |
| graphicsdrawText(graphics); |
| graphics.translate(-bounds.x, -bounds.y); |
| } |
| |
| /** |
| * Sets the label's icon to the passed image. |
| * |
| * @param image |
| * the new label image |
| * @since 2.0 |
| */ |
| public void setIcon(Image image) { |
| if (icon == image) |
| return; |
| icon = image; |
| // Call repaint, in case the image dimensions are the same. |
| repaint(); |
| if (icon == null) |
| setIconDimension(new Dimension()); |
| else |
| setIconDimension(new Dimension(image)); |
| } |
| |
| /** |
| * This method sets the alignment of the icon within the icon dimension. The |
| * dimension should be the same size as the Image itself, so calling this |
| * method should have no affect. |
| * |
| * @param align |
| * the icon alignment |
| * @since 2.0 |
| */ |
| public void setIconAlignment(int align) { |
| if (iconAlignment == align) |
| return; |
| iconAlignment = align; |
| clearLocations(); |
| repaint(); |
| } |
| |
| /** |
| * Sets the label's icon size to the passed Dimension. |
| * |
| * @param d |
| * the new icon size |
| * @since 2.0 |
| */ |
| public void setIconDimension(Dimension d) { |
| if (d.equals(iconSize)) |
| return; |
| iconSize = d; |
| revalidate(); |
| } |
| |
| /** |
| * Sets the gap in pixels between the label's icon and text to the passed |
| * value. The default is 4. |
| * |
| * @param gap |
| * the gap |
| * @since 2.0 |
| */ |
| public void setIconTextGap(int gap) { |
| if (iconTextGap == gap) |
| return; |
| iconTextGap = gap; |
| repaint(); |
| revalidate(); |
| } |
| |
| /** |
| * Sets the alignment of the entire label (icon and text). If this figure's |
| * bounds are larger than the size needed to display the label, the label |
| * will be aligned accordingly. Valid values are: |
| * <UL> |
| * <LI><EM>{@link PositionConstants#CENTER}</EM> |
| * <LI>{@link PositionConstants#TOP} |
| * <LI>{@link PositionConstants#BOTTOM} |
| * <LI>{@link PositionConstants#LEFT} |
| * <LI>{@link PositionConstants#RIGHT} |
| * </UL> |
| * |
| * @param align |
| * label alignment |
| */ |
| public void setLabelAlignment(int align) { |
| if (labelAlignment == align) |
| return; |
| labelAlignment = align; |
| clearLocations(); |
| repaint(); |
| } |
| |
| /** |
| * Sets the label's text. |
| * |
| * @param s |
| * the new label text |
| * @since 2.0 |
| */ |
| public void setText(String s) { |
| // "text" will never be null. |
| if (s == null) |
| s = ""; //$NON-NLS-1$ |
| if (text.equals(s)) |
| return; |
| text = s; |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * Sets the alignment of the Text relative to the icon. The text alignment |
| * must be orthogonal to the text placement. For example, if the placement |
| * is EAST, then the text can be aligned using TOP, CENTER, or BOTTOM. Valid |
| * values are: |
| * <UL> |
| * <LI><EM>{@link PositionConstants#CENTER}</EM> |
| * <LI>{@link PositionConstants#TOP} |
| * <LI>{@link PositionConstants#BOTTOM} |
| * <LI>{@link PositionConstants#LEFT} |
| * <LI>{@link PositionConstants#RIGHT} |
| * </UL> |
| * |
| * @see #setLabelAlignment(int) |
| * @param align |
| * the text alignment |
| * @since 2.0 |
| */ |
| public void setTextAlignment(int align) { |
| if (textAlignment == align) |
| return; |
| textAlignment = align; |
| clearLocations(); |
| repaint(); |
| } |
| |
| /** |
| * Sets the placement of text relative to the label's icon. Valid values |
| * are: |
| * <UL> |
| * <LI><EM>{@link PositionConstants#EAST}</EM> |
| * <LI>{@link PositionConstants#NORTH} |
| * <LI>{@link PositionConstants#SOUTH} |
| * <LI>{@link PositionConstants#WEST} |
| * </UL> |
| * |
| * @param where |
| * the text placement |
| * @since 2.0 |
| */ |
| public void setTextPlacement(int where) { |
| if (textPlacement == where) |
| return; |
| textPlacement = where; |
| revalidate(); |
| repaint(); |
| } |
| |
| private Rectangle getSelectionRectangle() { |
| Rectangle bounds = getTextBounds(); |
| bounds.expand(new Insets(2, 2, 0, 0)); |
| translateToParent(bounds); |
| bounds.intersect(getBounds()); |
| return bounds; |
| } |
| |
| /** |
| * Calculates and returns the size of the Label's text. Note that this |
| * Dimension is calculated using the Label's full text, regardless of |
| * whether or not its text is currently truncated. If text size considering |
| * current truncation is desired, use {@link #calculateSubStringTextSize()}. |
| * |
| * @return the size of the label's text, ignoring truncation |
| * @since 2.0 |
| */ |
| protected Dimension calculateTextSize(int width, int height) { |
| return FigureUtilities.getTextExtents(getWrappedText(width, height), |
| getFont()); |
| } |
| |
| // Code for the Text Wrap. |
| // Starts here. |
| |
| private String getWrappedText(int width, int height) { |
| if (!isTextWrapped() || width == -1) |
| return getText(); |
| |
| if (isIconExist()) { |
| switch (textPlacement) { |
| case EAST: |
| case WEST: |
| width -= iconSize.width + getIconTextGap(); |
| break; |
| case NORTH: |
| case SOUTH: |
| if (height != -1) |
| height -= iconSize.height + getIconTextGap(); |
| break; |
| } |
| } |
| |
| Font f = getFont(); |
| int maxLines = Integer.MAX_VALUE; |
| if (height != -1) { |
| int fontHeight = FigureUtilities.getFontMetrics(f).getHeight(); |
| maxLines = (int) (height / (double) fontHeight); |
| } |
| |
| StringBuffer accumlatedText = new StringBuffer(); |
| StringBuffer remainingText = new StringBuffer(getText()); |
| int i = 0, j = 0; |
| |
| while (remainingText.length() > 0 && j++ < maxLines) { |
| if ((i = getLineWrapPosition(remainingText.toString(), f, height)) == 0) |
| break; |
| |
| if (accumlatedText.length() > 0) |
| accumlatedText.append("\n"); //$NON-NLS-1$ |
| accumlatedText.append(remainingText.substring(0, i)); |
| remainingText.delete(0, i); |
| } |
| return accumlatedText.toString(); |
| } |
| |
| private boolean isIconExist() { |
| return true; |
| } |
| |
| private int getLineWrapPosition(String string, Font f, int width) { |
| BreakIterator iter = BreakIterator.getLineInstance(); |
| iter.setText(string); |
| int start = iter.first(); |
| int end = iter.next(); |
| |
| // if the first line segment does not fit in the width, |
| // determine the position within it where we need to cut |
| if (FigureUtilities.getTextExtents(string.substring(start, end), f).width > width) { |
| iter = BreakIterator.getCharacterInstance(); |
| iter.setText(string); |
| start = iter.first(); |
| } |
| |
| // keep iterating as long as width permits |
| do |
| end = iter.next(); |
| while (end != BreakIterator.DONE |
| && FigureUtilities.getTextExtents(string.substring(start, end), |
| f).width <= width); |
| return (end == BreakIterator.DONE) ? iter.last() : iter.previous(); |
| } |
| |
| /** |
| * Returns the largest substring of <i>s</i> in Font <i>f</i> that can be |
| * confined to the number of pixels in <i>availableWidth<i>. |
| * |
| * @param s |
| * the original string |
| * @param f |
| * the font |
| * @param availableWidth |
| * the available width |
| * @return the largest substring that fits in the given width |
| * @since 2.0 Copied from <class>FigureUtilities<class> Class, to avoid |
| * call of static. |
| */ |
| static int getLargestSubstringConfinedTo(String s, Font f, |
| int availableWidth) { |
| FontMetrics metrics = FigureUtilities.getFontMetrics(f); |
| int min, max; |
| float avg = metrics.getAverageCharWidth(); |
| min = 0; |
| max = s.length() + 1; |
| |
| // The size of the current guess |
| int guess = 0, guessSize = 0; |
| while ((max - min) > 1) { |
| // Pick a new guess size |
| // New guess is the last guess plus the missing width in pixels |
| // divided by the average character size in pixels |
| guess = guess + (int) ((availableWidth - guessSize) / avg); |
| |
| if (guess >= max) |
| guess = max - 1; |
| if (guess <= min) |
| guess = min + 1; |
| |
| // Measure the current guess |
| guessSize = FigureUtilities |
| .getTextExtents(s.substring(0, guess), f).width; |
| |
| if (guessSize < availableWidth) |
| // We did not use the available width |
| min = guess; |
| else |
| // We exceeded the available width |
| max = guess; |
| } |
| return min; |
| } |
| |
| /** |
| * Sets to wrap text in Label. |
| * |
| * @param b |
| * true/false |
| */ |
| public void setTextWrap(boolean b) { |
| if (isTextWrapped() == b) |
| return; |
| setFlag(FLAG_WRAP, b); |
| revalidate(); |
| repaint(); |
| } |
| |
| /** |
| * @return text wrap. |
| */ |
| public boolean isTextWrapped() { |
| return true; |
| } |
| |
| /** |
| * Set text wrap width. |
| * |
| * @param i |
| * The label text wrap width |
| */ |
| public void setTextWrapWidth(int i) { |
| if (this.wrapWidth == i) |
| return; |
| this.wrapWidth = i; |
| revalidate(); |
| repaint(); |
| |
| } |
| |
| /** |
| * Text Wrap Alignment, use only after using <method>setTextWrap(boolean)</method> |
| * |
| * @param i |
| * The label text wrapping width |
| */ |
| public void setTextWrapAlignment(int i) { |
| if (getTextWrapAlignment() == i) |
| return; |
| |
| setAlignmentFlags(i, FLAG_WRAP_ALIGN); |
| repaint(); |
| } |
| |
| /** |
| * setAlignmentFlags |
| * |
| * @param int |
| * align |
| * @param int |
| * flagOffset |
| * |
| * --- TODO - copied needs to modify |
| */ |
| private void setAlignmentFlags(int align, int flagOffset) { |
| flags &= ~(0x7 * flagOffset); |
| switch (align) { |
| case CENTER: |
| flags |= 0x1 * flagOffset; |
| break; |
| case TOP: |
| flags |= 0x2 * flagOffset; |
| break; |
| case LEFT: |
| flags |= 0x3 * flagOffset; |
| break; |
| case RIGHT: |
| flags |= 0x4 * flagOffset; |
| break; |
| case BOTTOM: |
| flags |= 0x5 * flagOffset; |
| break; |
| } |
| } |
| |
| /** |
| * |
| * @param wrapValue |
| * @return PositionConstant representing the alignment |
| */ |
| private int getAlignment(int flagOffset) { |
| int wrapValue = flags & (0x7 * flagOffset); |
| if (wrapValue == 0x1 * flagOffset) |
| return CENTER; |
| else if (wrapValue == 0x2 * flagOffset) |
| return TOP; |
| else if (wrapValue == 0x3 * flagOffset) |
| return LEFT; |
| else if (wrapValue == 0x4 * flagOffset) |
| return RIGHT; |
| else if (wrapValue == 0x5 * flagOffset) |
| return BOTTOM; |
| |
| return CENTER; |
| } |
| |
| /** |
| * @return the label text wrapping width |
| */ |
| public int getTextWrapAlignment() { |
| return getAlignment(FLAG_WRAP_ALIGN); |
| } |
| |
| /** |
| * @return the focus state of this label |
| */ |
| public boolean hasFocus() { |
| return (flags & FLAG_HASFOCUS) != 0; |
| } |
| |
| /** |
| * @return the selection state of this label |
| */ |
| public boolean isSelected() { |
| return (flags & FLAG_SELECTED) != 0; |
| } |
| |
| private void graphicsdrawText(Graphics graphics) { |
| String subString = getSubStringText(); |
| StringTokenizer tokenizer = new StringTokenizer(subString, "\n"); //$NON-NLS-1$ |
| |
| Font f = getFont(); |
| int fontHeight = FigureUtilities.getFontMetrics(f).getHeight(); |
| int textWidth = FigureUtilities.getTextExtents(subString, f).width; |
| int y = getTextLocation().y; |
| |
| // If the font's leading area is 0 then we need to add an offset to |
| // avoid truncating at the top (e.g. Korean fonts) |
| if (0 == FigureUtilities.getFontMetrics(f).getLeading()) { |
| int offset = 2; // 2 is the leading area for default English |
| y += offset; |
| } |
| |
| while (tokenizer.hasMoreTokens()) { |
| String token = tokenizer.nextToken(); |
| System.out.println("Text added to draw" + token); //$NON-NLS-1$ |
| int tokenWidth = FigureUtilities.getTextExtents(token, f).width; |
| int x = getTextLocation().x; |
| switch (getTextWrapAlignment()) { |
| case CENTER: |
| x += (textWidth - tokenWidth) / 2; |
| break; |
| case RIGHT: |
| x += textWidth - tokenWidth; |
| break; |
| } |
| graphics.drawText(token, x, y); |
| y += fontHeight; |
| } |
| } |
| |
| /** |
| * Sets the focus state of this label |
| * |
| * @param b |
| * true will cause a focus rectangle to be drawn around the text |
| * of the Label |
| */ |
| public void setFocus(boolean b) { |
| if (hasFocus() == b) |
| return; |
| setFlag(FLAG_HASFOCUS, b); |
| repaint(); |
| } |
| |
| /** |
| * Sets the selection state of this label |
| * |
| * @param b |
| * true will cause the label to appear selected |
| */ |
| public void setSelected(boolean b) { |
| if (isSelected() == b) |
| return; |
| setFlag(FLAG_SELECTED, b); |
| repaint(); |
| } |
| |
| } |