Contents | Package | Class | Tree | Deprecated | Index | Help | Java 1.2 Beta 3 | ||
PREV | NEXT | SHOW LISTS | HIDE LISTS |
java.lang.Object | +----java.awt.font.TextLayout
It provides the following capabilities:
TextLayout can be rendered by calling Graphics2D.drawString passing an instance of TextLayout and a position as the arguments.
TextLayout can be constructed either directly or through use of a LineBreakMeasurer. When constructed directly, the source text represents a single paragraph. LineBreakMeasurer provides support for line breaking to support wrapped text, see its documentation for more information.
TextLayout construction logically proceeds as follows:
All graphical information returned from TextLayout's methods is relative to the origin of the TextLayout, which is the intersection of the TextLayout's baseline with its left edge. Also, coordinates passed into TextLayout's methods are assumed to be relative to the TextLayout's origin. Clients will usually need to translate between TextLayout's coordinate system and the coordinate system in another object (such as a Graphics).
TextLayouts are constructed from styled text, but they do not retain a reference to their source text. Thus, changes in the text previously used to generate a TextLayout do not affect the TextLayout.
Three methods on TextLayout (getNextRightHit
,
getNextLeftHit
, and hitTestChar
) return instances
of TextHitInfo
. The offsets contained in these TextHitInfo's
are relative to the start of the TextLayout, not to the text used to
create the TextLayout. Similarly, TextLayout methods which accept
TextHitInfo instances as parameters expect the TextHitInfo's offsets to be
relative to the TextLayout, not to any underlying text storage model.
Examples:
Constructing and drawing a TextLayout and its bounding rectangle:
Graphics2D g = ...; Point2D loc = ...; Font font = Font.getFont("Helvetica-bold-italic"); TextLayout layout = new TextLayout("This is a string", font); g.drawString(layout, loc.getX(), loc.getY()); Rectangle2D bounds = layout.getBounds(); bounds.setRect(bounds.getX()+loc.getX(), bounds.getY()+loc.getY(), bounds.getWidth(), bounds.getHeight()) g.draw(bounds);
Hit-testing a TextLayout (determining which character is at a particular graphical location):
Point2D click = ...; TextHitInfo hit = layout.hitTestChar( (float) (click.getX() - loc.getX()), (float) (click.getY() - loc.getY()));
Displaying every caret position in a layout. Also, this demonstrates
how to correctly right-arrow from one TextHitInfo to another:
Drawing a selection range corresponding to a substring in the source text.
The selected area may not be visually contiguous:
Drawing a visually contiguous selection range. The selection range may
correspond to more than one substring in the source text. The ranges of
the corresponding source text substrings can be obtained with
All the text is styled using the provided attributes.
The string must specify a single paragraph of text, as an
entire paragraph is required for the bidirectional
algorithm.
The text must specify a single paragraph of text, as an
entire paragraph is required for the bidirectional
algorithm.
The iterator must specify a single paragraph of text, as an
entire paragraph is required for the bidirectional
algorithm.
If this layout has already been justified, an exception is thrown.
If this layout's justification ratio is zero, a layout identical to this
one is returned.
Some code may rely on immutablity of layouts. Subclassers should not
call this directly, but instead should call getJustifiedLayout, which
will call this method on a clone of this layout, preserving
the original.
The array is indexed by one of the values defined in Font (roman,
centered, hanging). The values are relative to this layout's baseline,
so that getBaselineOffsets[getBaseline()] == 0. Offsets
are added to the position of the layout's baseline to get the position
for the new baseline.
The leading is computed from the leading, descent, and baseline
of all glyphsets in the layout. The algorithm is roughly as follows:
This method is meant for informational use. To display carets, it
is better to use
If the selection includes the leftmost (topmost) position, the selection
is extended to the left (top) of the bounds. If the selection includes
the rightmost (bottommost) position, the selection is extended to the
right (bottom) of the bounds. The height (width on vertical lines) of
the selection is always extended to bounds.
Although the selection is always contiguous, the logically selected
text can be discontiguous on lines with mixed-direction text. The
logical ranges of text selected can be retrieved using
getLogicalRangesForVisualSelection. For example, consider the text
'ABCdef' where capital letters indicate right-to-left text, rendered
on a right-to-left line, with a visual selection from 0L (the leading
edge of 'A') to 3T (the trailing edge of 'd'). The text appears as
follows, with bold underlined areas representing the selection:
If the selection range includes the first logical character, the
selection is extended to the portion of bounds before the start of the
layout. If the range includes the last logical character, the
selection is extended to the portion of bounds after the end of
the layout. The height (width on vertical lines) of the selection is
always extended to bounds.
The selection can be discontiguous on lines with mixed-direction text.
Only those characters in the logical range between start and limit will
appear selected. For example consider the text 'ABCdef' where capital
letters indicate right-to-left text, rendered on a right-to-left line,
with a logical selection from 0 to 4 ('ABCd'). The text appears as
follows, with bold standing in for the selection, and underlining for
the extension:
// translate graphics to origin of layout on screen
g.translate(loc.getX(), loc.getY());
TextHitInfo hit = layout.isLeftToRight()?
TextHitInfo.trailing(-1) :
TextHitInfo.leading(layout.getCharacterCount());
for (; hit != null; hit = layout.getNextRightHit(hit.getInsertionOffset())) {
Shape[] carets = layout.getCaretShapes(hit.getInsertionOffset());
Shape caret = carets[0] == null? carets[1] : carets[0];
g.draw(caret);
}
// selStart, selLimit should be relative to the layout,
// not to the source text
int selStart = ..., selLimit = ...;
Color selectionColor = ...;
Shape selection = layout.getLogicalHighlight(selStart, selLimit);
// selection may consist of disjoint areas
// graphics is assumed to be tranlated to origin of layout
g.setColor(selectionColor);
g.fill(selection);
getLogicalRangesForVisualSelection()
:
TextOffset selStart = ..., selLimit = ...;
Shape selection = layout.getVisualHighlightSelection(selStart, selLimit);
g.setColor(selectionColor);
g.fill(selection);
int[] ranges = getLogicalRangesForVisualSelection(selStart, selLimit);
// ranges[0], ranges[1] is the first selection range,
// ranges[2], ranges[3] is the second selection range, etc.
Inner Class Summary
static
TextLayout.CaretPolicy
Field Summary
static TextLayout.CaretPolicy
DEFAULT_CARET_POLICY
Constructor Summary
TextLayout(String string,
Font font)
TextLayout(String string,
AttributeSet attributes)
TextLayout(StyledString text)
TextLayout(AttributedCharacterIterator text)
Method Summary
Object
clone()
void
draw(Graphics2D g2,
float x,
float y)
boolean
equals(Object obj)
boolean
equals(TextLayout layout)
float
getAdvance()
float
getAscent()
byte
getBaseline()
float[]
getBaselineOffsets()
Shape
getBlackBoxBounds(int firstEndpoint,
int secondEndpoint)
Rectangle2D
getBounds()
float[]
getCaretInfo(TextHitInfo hit,
Rectangle2D bounds)
float[]
getCaretInfo(TextHitInfo hit)
Shape
getCaretShape(TextHitInfo hit,
Rectangle2D bounds)
Shape
getCaretShape(TextHitInfo hit)
Shape[]
getCaretShapes(int offset,
Rectangle2D bounds,
TextLayout.CaretPolicy policy)
Shape[]
getCaretShapes(int offset,
Rectangle2D bounds)
Shape[]
getCaretShapes(int offset)
int
getCharacterCount()
byte
getCharacterLevel(int index)
float
getDescent()
TextLayout
getJustifiedLayout(float justificationWidth)
float
getLeading()
Shape
getLogicalHighlightShape(int firstEndpoint,
int secondEndpoint,
Rectangle2D bounds)
Shape
getLogicalHighlightShape(int firstEndpoint,
int secondEndpoint)
int[]
getLogicalRangesForVisualSelection(TextHitInfo firstEndpoint,
TextHitInfo secondEndpoint)
TextHitInfo
getNextLeftHit(TextHitInfo hit)
TextHitInfo
getNextLeftHit(int offset,
TextLayout.CaretPolicy policy)
TextHitInfo
getNextLeftHit(int offset)
TextHitInfo
getNextRightHit(TextHitInfo hit)
TextHitInfo
getNextRightHit(int offset,
TextLayout.CaretPolicy policy)
TextHitInfo
getNextRightHit(int offset)
float
getVisibleAdvance()
Shape
getVisualHighlightShape(TextHitInfo firstEndpoint,
TextHitInfo secondEndpoint,
Rectangle2D bounds)
Shape
getVisualHighlightShape(TextHitInfo firstEndpoint,
TextHitInfo secondEndpoint)
TextHitInfo
getVisualOtherHit(TextHitInfo hit)
void
handleJustify(float justificationWidth)
int
hashCode()
TextHitInfo
hitTestChar(float x,
float y,
Rectangle2D bounds)
TextHitInfo
hitTestChar(float x,
float y)
boolean
isLeftToRight()
boolean
isVertical()
String
toString()
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Field Detail
DEFAULT_CARET_POLICY
public static final TextLayout.CaretPolicy DEFAULT_CARET_POLICY
Constructor Detail
TextLayout
public TextLayout(String string,
Font font)
str
- the text to display.
font
- a font used to style the text.
TextLayout
public TextLayout(String string,
AttributeSet attributes)
str
- the text to display.
attributes
- the attributes used to style the text.
TextLayout
public TextLayout(StyledString text)
text
- the styled text to display.
TextLayout
public TextLayout(AttributedCharacterIterator text)
text
- the styled text to display.
Method Detail
clone
protected Object clone()
getJustifiedLayout
public TextLayout getJustifiedLayout(float justificationWidth)
justificationWidth
- the width to use when justifying the line.
For best results, it should not be too different from the current
advance of the line.
handleJustify
protected void handleJustify(float justificationWidth)
justificationWidth
- the width to use when justifying the line.
For best results, it should not be too different from the current
advance of the line.
getBaseline
public byte getBaseline()
getBaselineOffsets
public float[] getBaselineOffsets()
getAdvance
public float getAdvance()
getVisibleAdvance
public float getVisibleAdvance()
getAscent
public float getAscent()
getDescent
public float getDescent()
getLeading
public float getLeading()
maxD = 0;
maxDL = 0;
for (GlyphSet g in all glyphsets) {
maxD = max(maxD, g.getDescent() + offsets[g.getBaseline()]);
maxDL = max(maxDL, g.getDescent() + g.getLeading() +
offsets[g.getBaseline()]);
}
return maxDL - maxD;
getBounds
public Rectangle2D getBounds()
isLeftToRight
public boolean isLeftToRight()
isVertical
public boolean isVertical()
getCharacterCount
public int getCharacterCount()
getCaretInfo
public float[] getCaretInfo(TextHitInfo hit,
Rectangle2D bounds)
getCarets
.
hit
- a hit on a character in this layout
bounds
- the bounds to which the caret info is constructed
getCaretInfo
public float[] getCaretInfo(TextHitInfo hit)
getNextRightHit
public TextHitInfo getNextRightHit(TextHitInfo hit)
hit
- a hit on a character in this layout.
getNextRightHit
public TextHitInfo getNextRightHit(int offset,
TextLayout.CaretPolicy policy)
offset
- An insertion offset in this layout. Cannot be
less than 0 or greater than the layout's character count.
policy
- The policy used to select the strong caret.
getNextRightHit
public TextHitInfo getNextRightHit(int offset)
offset
- An insertion offset in this layout. Cannot be
less than 0 or greater than the layout's character count.
getNextLeftHit
public TextHitInfo getNextLeftHit(TextHitInfo hit)
hit
- a hit on a character in this layout.
getNextLeftHit
public TextHitInfo getNextLeftHit(int offset,
TextLayout.CaretPolicy policy)
offset
- An insertion offset in this layout. Cannot be
less than 0 or greater than the layout's character count.
policy
- The policy used to select the strong caret.
getNextLeftHit
public TextHitInfo getNextLeftHit(int offset)
offset
- An insertion offset in this layout. Cannot be
less than 0 or greater than the layout's character count.
getVisualOtherHit
public TextHitInfo getVisualOtherHit(TextHitInfo hit)
getCaretShape
public Shape getCaretShape(TextHitInfo hit,
Rectangle2D bounds)
getCaretShape
public Shape getCaretShape(TextHitInfo hit)
getCharacterLevel
public byte getCharacterLevel(int index)
getCaretShapes
public Shape[] getCaretShapes(int offset,
Rectangle2D bounds,
TextLayout.CaretPolicy policy)
offset
- an offset in the layout
bounds
- the bounds to which to extend the carets
getCaretShapes
public Shape[] getCaretShapes(int offset,
Rectangle2D bounds)
getCaretShapes
public Shape[] getCaretShapes(int offset)
getLogicalRangesForVisualSelection
public int[] getLogicalRangesForVisualSelection(TextHitInfo firstEndpoint,
TextHitInfo secondEndpoint)
firstEndpoint
- an endpoint of the visual range.
secondEndpoint
- the other enpoint of the visual range. Can be less than
firstEndpoint
.
getVisualHighlightShape
public Shape getVisualHighlightShape(TextHitInfo firstEndpoint,
TextHitInfo secondEndpoint,
Rectangle2D bounds)
defCBA
The logical selection ranges are 0-3, 4-6 (ABC, ef) because the
visually contiguous text is logically discontiguous. Also note that
since the rightmost position on the layout (to the right of 'A') is
selected, the selection is extended to the right of the bounds.
firstEndpoint
- one end of the visual selection
secondEndpoint
- the other end of the visual selection
bounds
- the bounding rectangle to which to extend the selection
getVisualHighlightShape
public Shape getVisualHighlightShape(TextHitInfo firstEndpoint,
TextHitInfo secondEndpoint)
getLogicalHighlightShape
public Shape getLogicalHighlightShape(int firstEndpoint,
int secondEndpoint,
Rectangle2D bounds)
defCBA
The selection is discontiguous because the selected characters are
visually discontiguous. Also note that since the range includes the
first logical character (A), the selection is extended to the portion
of the bounds before the start of the layout, which in this case
(a right-to-left line) is the right portion of the bounds.
firstEndpoint
- an endpoint in the range of characters to select
secondEndpoint
- the other endpoint of the range of characters
to select. Can be less than firstEndpoint
. The range
includes the character at min(firstEndpoint, secondEndpoint), but
excludes max(firstEndpoint, secondEndpoint).
bounds
- the bounding rectangle to which to extend the selection
getLogicalHighlightShape
public Shape getLogicalHighlightShape(int firstEndpoint,
int secondEndpoint)
getBlackBoxBounds
public Shape getBlackBoxBounds(int firstEndpoint,
int secondEndpoint)
firstEndpoint
- one end of the character range
secondEndpoint
- the other end of the character range. Can be
less than firstEndpoint
.
hitTestChar
public TextHitInfo hitTestChar(float x,
float y,
Rectangle2D bounds)
x
- the x offset from the origin of the layout
y
- the y offset from the origin of the layout
hitTestChar
public TextHitInfo hitTestChar(float x,
float y)
hashCode
public int hashCode()
equals
public boolean equals(Object obj)
equals
public boolean equals(TextLayout layout)
layout
- the layout to which to compare this layout.
toString
public String toString()
draw
public void draw(Graphics2D g2,
float x,
float y)
g2
- the graphics into which to render the layout
x
- the x position for the origin of the layout
y
- the y position for the origin of the layout
Contents | Package | Class | Tree | Deprecated | Index | Help
Java 1.2 Beta 3
PREV | NEXT
SHOW LISTS | HIDE LISTS
Submit a bug or feature
Submit comments/suggestions about new javadoc look.
Java is a trademark or registered trademark of Sun Microsystems, Inc. in the US and other countries.
Copyright 1993-1998 Sun Microsystems, Inc. 901 San Antonio Road, Palo Alto, California, 94303, U.S.A. All Rights Reserved.