Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-帮助在任意定位点绘制文本的最佳库_Java_Swing_Text_Graphics2d - Fatal编程技术网

Java-帮助在任意定位点绘制文本的最佳库

Java-帮助在任意定位点绘制文本的最佳库,java,swing,text,graphics2d,Java,Swing,Text,Graphics2d,我熟悉如何使用各种FontMetrics函数垂直、水平等方式将文本居中。但是,我正在寻找一个库,该库支持在相对于字符串的给定xy位置绘制文本(例如,我希望字符串的中心位于x、y,或者我希望它的右上角位于此处,等等) 我找到了它的文本锚,它声称可以做到这一点,但我很难让它正常工作 我知道我可以自己编写所有的实用程序函数,但如果可能的话,我希望避免重新发明轮子。我不知道有任何库,但我想如果您自己编写,您只需要使用Graphics.translate()将文本翻译到相对位置。您可能会看到。这些工具和方

我熟悉如何使用各种FontMetrics函数垂直、水平等方式将文本居中。但是,我正在寻找一个库,该库支持在相对于字符串的给定xy位置绘制文本(例如,我希望字符串的中心位于x、y,或者我希望它的右上角位于此处,等等)

我找到了它的文本锚,它声称可以做到这一点,但我很难让它正常工作


我知道我可以自己编写所有的实用程序函数,但如果可能的话,我希望避免重新发明轮子。

我不知道有任何库,但我想如果您自己编写,您只需要使用Graphics.translate()将文本翻译到相对位置。

您可能会看到。这些工具和方法可以简化编码。

最终不得不自己动手。代码如下:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class TestFontLayout extends JPanel {

    public enum AnchorPoint{
        UPPER_LEFT,
        TOP_CENTER,
        UPPER_RIGHT,
        RIGHT_CENTER,
        LOWER_RIGHT,
        BOTTOM_CENTER,
        LOWER_LEFT,
        LEFT_CENTER,
        CENTER
    };

    public void drawText(TextLayout text, AnchorPoint point, Graphics2D g2, float x, float y) {
        float translationX = 0.0f;
        float translationY = 0.0f;

        Rectangle2D bounds = text.getBounds();
        float midYOffset = (float) bounds.getHeight()/2;
        float midXOffset = (float) -bounds.getWidth()/2;

        float topYOffset = (float) bounds.getHeight();
        float bottomYOffset = 0.0f;

        float leftXOffset = 0.0f;
        float rightXOffset = (float) -bounds.getWidth();

        // Adjust x values
        switch (point) {
            // Left
            case UPPER_LEFT:
            case LOWER_LEFT:
            case LEFT_CENTER:
                translationX = leftXOffset;
                break;
                // Mid
            case TOP_CENTER:
            case BOTTOM_CENTER:
            case CENTER:
                translationX = midXOffset;
                break;
            // Right
            case UPPER_RIGHT:
            case RIGHT_CENTER:
            case LOWER_RIGHT:
                translationX = rightXOffset;
        }

        // Adjust y values
        switch (point) {
            // Top
            case UPPER_LEFT:
            case UPPER_RIGHT:
            case TOP_CENTER:
                translationY = topYOffset;
                break;
            // Mid
            case LEFT_CENTER:
            case CENTER:
            case RIGHT_CENTER:
                translationY = midYOffset;
                break;
            // Bottom
            case LOWER_LEFT:
            case BOTTOM_CENTER:
            case LOWER_RIGHT:
                translationY = bottomYOffset;
        }

        text.draw(g2, x + translationX, y + translationY);

    }

    public TestFontLayout() {
        super();
        setPreferredSize(new Dimension(400,400));
    }
    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        // Ensure that the default painting occurs
        super.paintComponent(g);

        Point2D loc = new Point2D.Double(getWidth()/2,getHeight()/2);
        Font font = Font.decode("Helvetica");
        FontRenderContext frc = g2.getFontRenderContext();
        TextLayout layout = new TextLayout("This is a string", font, frc);

        g2.setColor(Color.RED);
        g2.drawRect(getWidth()/2, getHeight()/2, 1,1);

        g2.setColor(Color.PINK);
        drawText(layout, AnchorPoint.UPPER_LEFT, g2, 0, 0);

        g2.setColor(Color.BLUE);
        drawText(layout, AnchorPoint.TOP_CENTER, g2, getWidth()/2, 0);

        g2.setColor(Color.ORANGE);
        drawText(layout, AnchorPoint.UPPER_RIGHT, g2, getWidth(), 0);

        g2.setColor(Color.CYAN);
        drawText(layout, AnchorPoint.RIGHT_CENTER, g2, getWidth(), getHeight()/2);

        g2.setColor(Color.ORANGE);
        drawText(layout, AnchorPoint.LOWER_RIGHT, g2, getWidth(), getHeight());

        g2.setColor(Color.BLACK);
        drawText(layout, AnchorPoint.BOTTOM_CENTER, g2, getWidth()/2, getHeight());


        g2.setColor(Color.YELLOW);
        drawText(layout, AnchorPoint.LOWER_LEFT, g2, 0, getHeight());

        g2.setColor(Color.DARK_GRAY);
        drawText(layout, AnchorPoint.LEFT_CENTER, g2, 0, getHeight()/2);


        g2.setColor(Color.MAGENTA);
        drawText(layout, AnchorPoint.CENTER, g2, getWidth()/2, getHeight()/2);
    }


    public static void main(String[] args) {
        JFrame frame = new JFrame("");
        frame.add(new TestFontLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);

    }
}

我发现
TestFontLayout
Codeby非常有用,谢谢。垂直对齐中有一个小错误。我的解决方案是使用
bounds.getY()
而不是
bounds.getHeight()
进行“偏移”计算。此外,
drawText(…)
方法已修改为返回自定义的
Box
类,以提供绘制文本的角坐标,以便下一个图形可以使用方框角对齐更多文本。这是我的代码版本

import static java.awt.Color.BLACK;
import static java.awt.Color.BLUE;
import static java.awt.Color.CYAN;
import static java.awt.Color.DARK_GRAY;
import static java.awt.Color.MAGENTA;
import static java.awt.Color.ORANGE;
import static java.awt.Color.PINK;
import static java.awt.Color.RED;
import static java.awt.Color.YELLOW;
import static java.awt.Font.PLAIN;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class TestFontLayout2 extends JPanel
{
    private static final long serialVersionUID = 1L;

    public enum Anchor
    {
        UPPER_LEFT,
        UPPER_CENTER,
        UPPER_RIGHT,
        MIDDLE_LEFT,
        MIDDLE_CENTER,
        MIDDLE_RIGHT,
        LOWER_LEFT,
        LOWER_CENTER,
        LOWER_RIGHT
    };

    public static Box drawText(Graphics2D g2d, String text, Anchor point, float xpos, float ypos)
    {
        return drawText(g2d, new TextLayout(text, g2d.getFont(), g2d.getFontRenderContext()), point, xpos, ypos);
    }
    
    public static Box drawText(Graphics2D g2d, String text, Anchor point, float xpos, float ypos, Font font)
    {
        return drawText(g2d, new TextLayout(text, font, g2d.getFontRenderContext()), point, xpos, ypos);
    }
    
    public static Box drawText(Graphics2D g2d, TextLayout text, Anchor anchor, float xpos, float ypos)
    {
        Rectangle2D bounds = text.getBounds();

        float xOffsetLeft = 0.0f;
        float xOffsetRight = (float) -bounds.getWidth();
        float xOffsetCenter = (float) -bounds.getWidth() / 2.0f;
        
        // Bounds.getY() is the (negative) offset between the baseline and the top of the text.
        // Bounds.getHeight() is the distance above plus the distance below the text baseline.
        float yOffsetTop = (float) bounds.getY();
        float yOffsetBottom = (float) (bounds.getHeight()+bounds.getY());
        float yOffsetMiddle = (float) (-bounds.getHeight()) / 2.0f;
        
        float xOffset = 0.0f;
        float yOffset = 0.0f;

        // Adjust x values
        switch (anchor)
        {
            // Left
            case UPPER_LEFT:
            case MIDDLE_LEFT:
            case LOWER_LEFT:
                xOffset = xOffsetLeft;
                break;
            // Center
            case UPPER_CENTER:
            case MIDDLE_CENTER:
            case LOWER_CENTER:
                xOffset = xOffsetCenter;
                break;
            // Right
            case UPPER_RIGHT:
            case MIDDLE_RIGHT:
            case LOWER_RIGHT:
                xOffset = xOffsetRight;
                break;
        }

        // Adjust y values
        switch (anchor)
        {
            // Top
            case UPPER_LEFT:
            case UPPER_CENTER:
            case UPPER_RIGHT:
                yOffset = yOffsetTop;
                break;
            // Middle
            case MIDDLE_LEFT:
            case MIDDLE_CENTER:
            case MIDDLE_RIGHT:
                yOffset = yOffsetMiddle;
                break;
            // Bottom
            case LOWER_LEFT:
            case LOWER_CENTER:
            case LOWER_RIGHT:
                yOffset = yOffsetBottom;
                break;
        }
        
        // Draw text at baseline position.
        float xbase = xpos + xOffset;
        float ybase = ypos - yOffset;
        text.draw(g2d, xbase, ybase);
        
        // Enclose text within a box.
        int xrect = rnd(xbase + bounds.getX());
        int yrect = rnd(ybase + bounds.getY());
        int wrect = rnd(bounds.getWidth());
        int hrect = rnd(bounds.getHeight());
        Box box = new Box(xrect, yrect, xrect+wrect, yrect+hrect);

        // Debug: draw rectangle around text.
        // g2d.drawRect(xrect, yrect, wrect, hrect);
        
        return box;
    }
    
    private static int rnd(double value)
    {
        return (int) Math.round(value);
    }

    public static class Box
    {
        private int tl[] = {0, 0}; public int[] getTL() { return tl; }
        private int br[] = {0, 0}; public int[] getBR() { return br; }
        private int tr[] = {0, 0}; public int[] getTR() { return tr; }
        private int bl[] = {0, 0}; public int[] getBL() { return bl; }
        
        public Box(int tlx, int tly, int brx, int bry)
        {
            tl[0] = tlx; tl[1] = tly;
            br[0] = brx; br[1] = bry;
            tr[0] = brx; tr[1] = tly;
            bl[0] = tlx; bl[1] = bry;
        }
    }

    public TestFontLayout2()
    {
        super();
        setPreferredSize(new Dimension(600,300));
    }

    @Override
    public void paintComponent(Graphics g)
    {
        Graphics2D g2d = (Graphics2D) g;
        
        // Ensure that the default painting occurs
        super.paintComponent(g);

        Font font = new Font("SansSerif", PLAIN, 21);
        FontRenderContext frc = g2d.getFontRenderContext();
        TextLayout layout1 = new TextLayout("This is a string", font, frc);
        TextLayout layout2 = new TextLayout("This is text", font, frc);

        g2d.setColor(RED);
        g2d.drawRect(getWidth()/2, getHeight()/2, 1,1);

        g2d.setColor(PINK);
        Box box = drawText(g2d, layout1, Anchor.UPPER_LEFT, 0, 0);

        g2d.setColor(BLUE);
        box = drawText(g2d, layout2, Anchor.UPPER_CENTER, getWidth()/2, 0);

        g2d.setColor(ORANGE);
        box = drawText(g2d, layout1, Anchor.UPPER_RIGHT, getWidth(), 0);

        g2d.setColor(DARK_GRAY);
        box = drawText(g2d, layout2, Anchor.MIDDLE_LEFT, 0, getHeight()/2);

        g2d.setColor(MAGENTA);
        box = drawText(g2d, layout1, Anchor.MIDDLE_CENTER, getWidth()/2, getHeight()/2);
        box = drawText(g2d, layout1, Anchor.UPPER_LEFT, box.getBL()[0], box.getBL()[1]);

        g2d.setColor(CYAN);
        box = drawText(g2d, layout2, Anchor.MIDDLE_RIGHT, getWidth(), getHeight()/2);

        g2d.setColor(YELLOW);
        box = drawText(g2d, layout1, Anchor.LOWER_LEFT, 0, getHeight());

        g2d.setColor(BLACK);
        box = drawText(g2d, layout2, Anchor.LOWER_CENTER, getWidth()/2, getHeight());

        g2d.setColor(ORANGE);
        box = drawText(g2d, layout1, Anchor.LOWER_RIGHT, getWidth(), getHeight());
    }

    public static void main(String[] args)
    {
        println("Draw text at specified anchor points...");
        JFrame frame = new JFrame("");
        frame.add(new TestFontLayout2());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);

    }

    private static void println(Object obj)
    {
        System.out.println(obj.toString());
    }
}
// vi:set tabstop=4 hardtabs=4 shiftwidth=4 expandtab:

绝对可以通过仿射变换进行转换。我将等待,直到我看到在未来几天的反应是什么;如果什么都没有出现,我将尝试深入JCommons的源代码并修复该bug,或者自己编写。从“迟做总比不做好”部门,您在论坛上报告的bug已经在JCommon 1.0.20版本中修复。此外,对于您试图实现的目标,TextUtilities.drawAlignedString()方法将是最佳选择。感谢您的更新。我忘了这个问题。