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

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

请帮帮我,我迷路了^^

最佳答案

错误是在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;
}
}

关于java - 使用 Java Graphics2D API 在 TextLayout 中将文本右对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13323701/

相关文章:

java - 在 Swing 中重新绘制时识别 Graphics2D 的脏区

java - 如何在不更改其位置的情况下旋转图形对象?

java - 为什么它只绘制其中一个组件?

java - 斜面 java (带角的三角形)

java - 更改和删除按钮的方法

java - 如何在 java 中使用 Elasticsearch Rest api?

Java 观察者模式 - 如何在更新(通知)循环/迭代期间删除观察者?

java - IntelliJ Idea 2018.2没有导入gradle项目的选项

java - OnClick 后 Activity 关闭

java - JPanel 宽度超过 getPreferredSize() 中定义的尺寸