使用Java Graphics2D API在TextLayout中右对齐文本

时间:2012-11-10 16:19:36

标签: java graphics2d

所以,我正在使用Java教程中的代码绘制一段文本,但我不知道如何将文本与右边距对齐。

我刚刚将attstring.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_RTL);包含在该案例的代码中,但它不起作用。

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;
    }

请一只手,我迷路了^^

1 个答案:

答案 0 :(得分:3)

错误在drawPosX的计算中。工作公式为drawPosX = (float) x + breakWidth - layout.getAdvance();

我最后做了一些修复以支持中心对齐,这是代码:

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;
}
}