Reputation: 1371
So, I'm using the code in Java tutorial to draw a piece of text, but I don't know how to align text to the right margin.
I just included attstring.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_RTL);
in the code for that case but it doesn't work.
protected float drawParagraph (Graphics2D g2, String text, float width, float x, float y, Boolean dir){
AttributedString attstring = new AttributedString(text);
attstring.addAttribute(TextAttribute.FONT, font);
if (dir == TextAttribute.RUN_DIRECTION_RTL){
attstring.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_RTL);
}
AttributedCharacterIterator paragraph = attstring.getIterator();
int paragraphStart = paragraph.getBeginIndex();
int paragraphEnd = paragraph.getEndIndex();
FontRenderContext frc = g2.getFontRenderContext();
LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(paragraph, frc);
// Set break width to width of Component.
float breakWidth = width;
float drawPosY = y;
// Set position to the index of the first character in the paragraph.
lineMeasurer.setPosition(paragraphStart);
// Get lines until the entire paragraph has been displayed.
while (lineMeasurer.getPosition() < paragraphEnd) {
// Retrieve next layout. A cleverer program would also cache
// these layouts until the component is re-sized.
TextLayout layout = lineMeasurer.nextLayout(breakWidth);
// Compute pen x position. If the paragraph is right-to-left we
// will align the TextLayouts to the right edge of the panel.
// Note: drawPosX is always where the LEFT of the text is placed.
float drawPosX = (float) (layout.isLeftToRight()
? x : breakWidth - layout.getAdvance());
// Move y-coordinate by the ascent of the layout.
drawPosY += layout.getAscent();
// Draw the TextLayout at (drawPosX, drawPosY).
layout.draw(g2, drawPosX, drawPosY);
// Move y-coordinate in preparation for next layout.
drawPosY += layout.getDescent() + layout.getLeading();
}
return drawPosY;
}
Give a hand please, I'm lost ^^
Upvotes: 3
Views: 2952
Reputation: 1371
The error was in the calculation of drawPosX
. The working formula is drawPosX = (float) x + breakWidth - layout.getAdvance();
I ended up doing a little fix to support center alignment and here is the code:
public abstract class MyClass extends JPanel implements Printable{
[...]
public static enum Alignment {RIGHT, LEFT, CENTER};
[...]
/**
* Draw paragraph.
* Pinta un parrafo segun las localizaciones pasadas como parametros.
*
* @param g2 Drawing graphic.
* @param text String to draw.
* @param width Paragraph's desired width.
* @param x Start paragraph's X-Position.
* @param y Start paragraph's Y-Position.
* @param dir Paragraph's alignment.
* @return Next line Y-position to write to.
*/
protected float drawParagraph (Graphics2D g2, String text, float width, float x, float y, Alignment alignment){
AttributedString attstring = new AttributedString(text);
attstring.addAttribute(TextAttribute.FONT, font);
AttributedCharacterIterator paragraph = attstring.getIterator();
int paragraphStart = paragraph.getBeginIndex();
int paragraphEnd = paragraph.getEndIndex();
FontRenderContext frc = g2.getFontRenderContext();
LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(paragraph, frc);
// Set break width to width of Component.
float breakWidth = width;
float drawPosY = y;
// Set position to the index of the first character in the paragraph.
lineMeasurer.setPosition(paragraphStart);
// Get lines until the entire paragraph has been displayed.
while (lineMeasurer.getPosition() < paragraphEnd) {
// Retrieve next layout. A cleverer program would also cache
// these layouts until the component is re-sized.
TextLayout layout = lineMeasurer.nextLayout(breakWidth);
// Compute pen x position.
float drawPosX;
switch (alignment){
case RIGHT:
drawPosX = (float) x + breakWidth - layout.getAdvance();
break;
case CENTER:
drawPosX = (float) x + (breakWidth - layout.getAdvance())/2;
break;
default:
drawPosX = (float) x;
}
// Move y-coordinate by the ascent of the layout.
drawPosY += layout.getAscent();
// Draw the TextLayout at (drawPosX, drawPosY).
layout.draw(g2, drawPosX, drawPosY);
// Move y-coordinate in preparation for next layout.
drawPosY += layout.getDescent() + layout.getLeading();
}
return drawPosY;
}
}
Upvotes: 3