All Packages Class Hierarchy This Package Previous Next Index
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:
AffineTransform translate = new AffineTransform();
translate.setToTranslation(loc.getX(), loc.getY());
TextHitInfo hit = new TextHitInfo(-1, TextHitInfo.TRAILING);
for (; hit != null; hit = layout.getNextRightHit(hit)) {
Shape[] shapes = layout.getCaretShapes(hit);
Shape shape = shapes[0] == null? shapes[1] : shapes[0];
shape = translate.createTransformedShape(shape);
g.draw(shape);
}
// selStart, selLimit should be relative to the layout,
// not to the source text
int selStart = ..., selLimit = ...;
Color selectionColor = ...;
Shape selection = layout.getLogicalHighlightShape(selStart, selLimit);
// selection may consist of disjoint areas
selection = translation.createTransformedShape(selection);
g.setColor(selectionColor);
g.fill(selection);
getLogicalRangesForVisualSelection()
:
TextOffset selStart = ..., selLimit = ...;
Shape selection = layout.getVisualHighlightSelection(selStart, selLimit);
selection = translation.createTransformedShape(selection);
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.
TextLayout(AttributedCharacterIterator)
TextLayout(String, AttributeSet)
TextLayout(String, Font)
TextLayout(StyledString)
clone()
draw(Graphics2D, float, float)
equals(Object)
equals(TextLayout)
getAdvance()
getAscent()
getBaseline()
getBaselineOffsets()
getBlackBoxBounds(int, int)
getBounds()
getCaretInfo(TextHitInfo)
getCaretShapes(TextHitInfo)
getCaretShapes(TextHitInfo, Rectangle2D)
getCharacterCount()
getDescent()
getJustifiedLayout(float)
getLeading()
getLogicalHighlightShape(int, int)
getLogicalHighlightShape(int, int, Rectangle2D)
getLogicalRangesForVisualSelection(TextHitInfo, TextHitInfo)
getNextLeftHit(TextHitInfo)
getNextRightHit(TextHitInfo)
getVisibleAdvance()
getVisualHighlightShape(TextHitInfo, TextHitInfo)
getVisualHighlightShape(TextHitInfo, TextHitInfo, Rectangle2D)
handleJustify(float)
hashCode()
hitTestChar(float, float)
isLeftToRight()
isVertical()
toString()
TextLayout
public TextLayout(String string,
Font font)
TextLayout
public TextLayout(String string,
AttributeSet attributes)
TextLayout
public TextLayout(StyledString text)
TextLayout
public TextLayout(AttributedCharacterIterator text)
clone
protected Object clone()
getJustifiedLayout
public TextLayout getJustifiedLayout(float justificationWidth)
handleJustify
protected void handleJustify(float justificationWidth)
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)
getCaretShapes
.
getNextRightHit
public TextHitInfo getNextRightHit(TextHitInfo hit)
getNextLeftHit
public TextHitInfo getNextLeftHit(TextHitInfo hit)
getCaretShapes
public Shape[] getCaretShapes(TextHitInfo hit,
Rectangle2D bounds)
getCaretShapes
public Shape[] getCaretShapes(TextHitInfo hit)
getLogicalRangesForVisualSelection
public int[] getLogicalRangesForVisualSelection(TextHitInfo startHit,
TextHitInfo limitHit)
getVisualHighlightShape
public Shape getVisualHighlightShape(TextHitInfo startHit,
TextHitInfo limitHit,
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.
getVisualHighlightShape
public Shape getVisualHighlightShape(TextHitInfo startHit,
TextHitInfo limitHit)
getLogicalHighlightShape
public Shape getLogicalHighlightShape(int start,
int limit,
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.
getLogicalHighlightShape
public Shape getLogicalHighlightShape(int start,
int limit)
getBlackBoxBounds
public Shape getBlackBoxBounds(int start,
int limit)
hitTestChar
public TextHitInfo hitTestChar(float x,
float y)
hashCode
public int hashCode()
equals
public boolean equals(Object obj)
equals
public boolean equals(TextLayout layout)
toString
public String toString()
draw
public void draw(Graphics2D g2,
float x,
float y)
All Packages Class Hierarchy This Package Previous Next Index
Submit a bug or feature