📄 label.java
字号:
package org.j4me.ui.components;
import java.util.*;
import javax.microedition.lcdui.*;
import org.j4me.ui.*;
/**
* Displays a string.
* <p>
* If the string is wider than the screen, it is wrapped at the first
* non-alphanumeric character. The wrapped text is trimmed so that
* leading spaces do not appear. There are several special markup
* strings for controling spacing:
* <ul>
* <li><code>\n</code> - Goes to a newline and adds a 1/2 space separator
* <li><code>\r</code> - Goes to a newline, but does not add a separator
* </ul>
* The string is displayed using the theme's font and color unless
* overridden by the <code>setFont</code> and <code>setFontColor</code> methods.
* <p>
* Override this class to display strings in a new way. For example
* a font backed by images of the characters can be used by re-implementing
* <code>paint</code>, <code>getWidth</code>, and <code>getHeight</code>. A good way to
* generate font images is with the <a href="- http://www.angelcode.com/products/bmfont/">
* AngelCode Bitmap Font Generator</a>.
*/
public class Label
extends Component
{
/**
* The string that is displayed by this label.
*/
private String text;
/**
* Each element is a substring of <code>text</code> that appears on a single
* line.
*/
private String[] lines;
/**
* The width in pixels used to create the <code>lines</code> array. If <code>lines</code>
* is <code>null</code> this has no meaning.
*/
private int widthForLines;
/**
* The height, in pixels, it takes to write all the lines.
*/
private int height;
/**
* The font to use for this label. If <code>null</code> the theme's font
* will be used.
*/
private Font font;
/**
* The font color to use for this label. If negative the theme's font
* will be used.
*/
private int fontColor = -1;
/**
* Constructs an empty label. The test should be set using <code>setLabel</code>.
*/
public Label ()
{
}
/**
* Constructs a label.
*
* @param text is what the label displays.
*/
public Label (String text)
{
setLabel( text );
}
/**
* @return The text this label will display.
*/
public String getLabel ()
{
return text;
}
/**
* @param text is the string to display. If <code>null</code> the label will
* be hidden.
*/
public synchronized void setLabel (String text)
{
this.text = text;
this.lines = null;
}
/**
* @return The <code>Font</code> used to display the label. If <code>null</code> the
* theme's font will be used.
*
* @see Theme#getFont()
*/
public Font getFont ()
{
return font;
}
/**
* Returns the font used by the label. This differs from <code>getFont()</code>
* because if the user has not overriden the font, the theme's font will
* be returned.
*
* @param theme is the application's theme.
* @return The <code>Font</code> used by the label.
*/
private Font getFont (Theme theme)
{
if ( font != null )
{
return font;
}
else
{
return theme.getFont();
}
}
/**
* @param font is the font to use for this label. If <code>null</code> the
* theme's font will be used.
*
* @see Theme#getFont()
*/
public synchronized void setFont (Font font)
{
this.font = font;
this.lines = null;
}
/**
* @return The font color used to display the label. If negative the
* theme's font will be used.
*
* @see Theme#getFontColor()
*/
public int getFontColor ()
{
return fontColor;
}
/**
* Returns the font color by the label. This differs from
* <code>getFontColor()</code> because if the user has not overriden the font color,
* the theme's font color will be returned.
*
* @param theme is the application's theme.
* @return The font color used by the label.
*/
private int getFontColor (Theme theme)
{
if ( fontColor >= 0 )
{
return fontColor;
}
else
{
return theme.getFontColor();
}
}
/**
* @param color is the font color used to display the label. If negative the
* theme's font will be used.
*
* @see Theme#getFontColor()
*/
public void setFontColor (int color)
{
this.fontColor = color;
}
/**
* Paints this label component.
*
* @param g is the <code>Graphics</code> object to be used for rendering the item.
* @param theme is the application's theme. Use it to get fonts and colors.
* @param width is the width, in pixels, to paint the component.
* @param height is the height, in pixels, to paint the component.
* @param selected is <code>true</code> when this components is currently selected
* and <code>false</code> when it is not.
*
* @see org.j4me.ui.components.Component#paintComponent(Graphics, Theme, int, int, boolean)
*/
protected synchronized void paintComponent (Graphics g, Theme theme, int width, int height, boolean selected)
{
if ( text != null )
{
// Set the font on the graphics object.
Font font = getFont( theme );
g.setFont( font );
int fontColor = getFontColor( theme );
g.setColor( fontColor );
int fontHeight = font.getHeight();
int paragraphSpacing = fontHeight / 2;
// Determine the positioning of the line.
int x;
int y = 0;
int horizontalAlignment = getHorizontalAlignment();
int anchor = horizontalAlignment | Graphics.TOP;
if ( horizontalAlignment == Graphics.LEFT )
{
x = 0;
}
else if ( horizontalAlignment == Graphics.HCENTER )
{
x = width / 2;
}
else // horizontalAlignment == Graphics.RIGHT
{
x = width;
}
// Do we need to break apart the text again?
// If we have not fit this label's text into the
// specified width for the component, reparse it.
if ( (lines == null) || (widthForLines != width) )
{
lines = breakIntoLines( font, text, width );
widthForLines = width;
}
// Get the top and bottom of current graphics clip.
int clipTop = g.getClipY();
int clipBottom = clipTop + g.getClipHeight();
// Draw each line.
for ( int i = 0; i < lines.length; i++ )
{
if ( lines[i] == null )
{
y += paragraphSpacing;
}
else
{
if ( (y + fontHeight >= clipTop) && (y <= clipBottom) )
{
g.drawString( lines[i], x, y, anchor );
}
y += fontHeight;
}
}
// Record the height of this component.
this.height = y;
}
}
/**
* Returns the dimensions of the label for the current string.
* The width is equal to the width of the longest line of text.
* The height is equal to the sum of all the lines including
* line breaks between paragraphs.
*
* @see org.j4me.ui.components.Component#getPreferredComponentSize(Theme, int, int)
*/
protected int[] getPreferredComponentSize (Theme theme, int viewportWidth, int viewportHeight)
{
int width = 0;
height = 0;
if ( text != null )
{
// Get the font.
Font font = getFont( theme );
// Parse the text by line breaks.
if ( (lines == null) || (widthForLines != viewportWidth) )
{
lines = breakIntoLines( font, text, viewportWidth );
widthForLines = viewportWidth;
}
// Get the width and height.
int fontHeight = font.getHeight();
int paragraphSpacing = fontHeight / 2;
for ( int i = 0; i < lines.length; i++ )
{
if ( lines[i] == null )
{
// Space between paragraphs.
height += paragraphSpacing;
}
else
{
int lineWidth = font.stringWidth( lines[i] );
if ( lineWidth > width )
{
width = lineWidth;
}
height += fontHeight;
}
}
}
return new int[] { width, height };
}
/**
* @return The height, in pixels, for this component.
*/
public int getHeight ()
{
if ( lines == null )
{
return super.getHeight();
}
else
{
return height;
}
}
/**
* Breaks <code>string</code> apart at line breaks. The returned array has
* strings that can be written using <code>font</code> in fewer than <code>width</code>
* pixels.
* <p>
* The <code>string</code> will be split apart at non-alphanumeric characters.
* However, if a string is too long and cannot be broken nicely, it will
* be split at the last alphanumeric character that fits the line
* <code>width</code>.
* <p>
* Newline characters (<code>'\n'</code>) are automatically made into line
* breaks. An additional empty line, represented by a <code>null</code>
* string in the returned array, is added. It can then be painted as
* a space to indicate a new paragraph.
*
* @param font is the <code>Font</code> used to write <code>string</code>.
* @param string is the text to split. If <code>null</code> then <code>null</code>
* will be returned.
* @param width is the maximum number of pixels wide each string part
* can be.
* @return An array of parts of <code>string</code> broken apart at line
* breaks.
*/
public static String[] breakIntoLines (Font font, String string, int width)
{
String[] lines = null;
if ( string != null )
{
// A container for holding lines as we parse them.
Vector parsedLines = new Vector();
String newLine;
// The index of the character that starts this line.
int lineStart = 0;
// The index of a character that may appear on the
// next line. For example a space can appear on this
// line or the next, but a letter in the middle of the
// word must stay on the same line as the entire word.
int lastBreakableSpot = 0;
// The index of the last character that wasn't a
// whitespace character such as ' '.
int lastNonWhiteSpace = 0;
// The width of a wide character used as a safety
// margin in calculating the line width. Not all font
// width calculations are reliable (e.g. the default
// font on the Motorola SLVR). Adjusting the line
// width by this amount assures no text will get clipped.
int charWidth = font.charWidth( 'O' );
width -= charWidth;
// Scan lengths character-by-character.
char[] chars = string.toCharArray();
for ( int i = 0; i < chars.length; i++ )
{
boolean isSeparator =
(chars[i] == '-') ||
(chars[i] == '/');
boolean isWhiteSpace =
(chars[i] == ' ');
boolean isNewLine =
(chars[i] == '\n');
boolean isCarrageReturn =
(chars[i] == '\r');
boolean isLineBreak = isNewLine || isCarrageReturn;
int lineWidth = font.charsWidth( chars, lineStart, i - lineStart );
// Are we done with this line?
if ( (isLineBreak) || (lineWidth > width) )
{
int lineEnd;
if ( isLineBreak )
{
lineEnd = i;
}
else if ( lastBreakableSpot > lineStart )
{
lineEnd = lastBreakableSpot;
}
else
{
// This word is longer than the line so do a mid-word break
// with the current letter on the next line.
lineEnd = i - 1;
}
// Record the line.
newLine = string.substring( lineStart, lineEnd ).trim();
parsedLines.addElement( newLine );
// Setup for the next line.
if ( isLineBreak )
{
lineStart = lineEnd + 1; // +1 to advance over the '\n'
// Add an empty line between the paragraphs.
if ( isNewLine )
{
parsedLines.addElement( null );
}
}
else // line break in the middle of a paragraph
{
lineStart = lineEnd;
}
}
// Is this a good place for a line-break?
if ( isSeparator )
{
// Put the separator char on this line (e.g. "full-").
lastBreakableSpot = i + 1;
}
if ( isWhiteSpace )
{
// Break at the whitespace. It will be trimmed later.
lastBreakableSpot = lastNonWhiteSpace + 1;
}
else
{
// Record this character as the last non-whitespace processed.
lastNonWhiteSpace = i;
}
}
// Add the last line.
newLine = string.substring( lineStart ).trim();
parsedLines.addElement( newLine );
// Convert the vector into a string array.
lines = new String[parsedLines.size()];
Enumeration e = parsedLines.elements();
int i = 0;
while ( e.hasMoreElements() )
{
lines[i++] = (String)e.nextElement();
}
}
return lines;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -