【问题标题】:Draw scaled string in swing relative to rectangle相对于矩形在摆动中绘制缩放字符串
【发布时间】:2013-09-21 23:56:27
【问题描述】:

我需要使用java.awt.Graphics2d 放置一些几何图元和文本。如果我缩放它们,我希望元素彼此的相对位置是与比例无关的。不幸的是,如果我只是使用Graphics2D.scale(...) 来绘制一些带有Graphics2D.drawRectangle(...)Graphics2D.drawString(...) 的对象,则相对位置会发生变化。用这张图来说明就好了:

所以这是产生此图像的代码:

public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setTitle("Title");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(new JPanel() {
            {
                setPreferredSize(new Dimension(1024, 300));
            }

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2 = (Graphics2D) g;
                g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

                for(int i = 1; i < 5; i++) {
                    doDraw(g2, i, i*10);
                }
            }

            void doDraw(Graphics2D g2, double scale, int yOffset) {
                String txt = "A-->                                                B";

                AffineTransform at = g2.getTransform();

                g2.scale(scale, scale);
                g2.setColor(Color.DARK_GRAY);
                g2.drawRect(10, 10 + yOffset, 234, 20);
                g2.drawString(txt, 14, 24 + yOffset);

                g2.setColor(Color.red);
                g2.drawOval(228, 12 + yOffset, 14, 14);

                g2.setTransform(at);
            }
        });

        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

如您所见,元素的位置是恒定的。唯一改变的是规模。 100% 时,红色圆圈正好在 B 字母上。但在 300% 或更多时,它是完全错误的。我做错了什么还是java中的错误?有没有解决这个问题的方法?

我真正想要实现的是,在任何比例下,红色圆圈总是围绕字母“B”绘制。

UPD: 我认为它发生的原因是 java 如何渲染缩放字体。这不仅仅是字体,它像几何操作一样缩放,但对于任何比例,java 都采用适当的点大小字体。因此,75% 的 Arial 8 渲染为与 Arial 6 一样,而不是 Arial 8 在 3/4 上按比例缩小。否则,缩放的文本看起来会很糟糕。但也许我错了。

UPD 2:试过 SwingUtilities2.drawText() - 没有效果。

背景:其实我正在制作一种矢量编辑程序。所以我在文档中有对象,它们有 X、Y 坐标。所以我只想以某种方式将它们放在文档中。问题是通过改变缩放,对象在它们彼此的相对位置“跳跃”。因此,如果我想制作一些像 CHECKED 这样的文本并将字母 C 放在一个盒子/圆圈中,这取决于比例。

【问题讨论】:

  • 另请注意,“B”的位置高度依赖于字体指标。您依赖它在每个平台上都完全相同。
  • @kiheru 如果两台机器只使用一个字体文件,应该是一样的……还是不一样?
  • Java 字体不能线性缩放,因为要处理空格等字符的小数宽度。您可以尝试的另一种方法是以固定的标准尺寸绘制到单独的 BufferedImage,然后对其执行缩放操作。
  • 我不确定。 OpenJDK 使用 freetype 进行字体光栅化,但 Oracle 品牌的 JDK 可能使用其他东西,因此可能存在差异。

标签: java swing graphics2d text-rendering


【解决方案1】:

您应该使用g.getFontMetrics(font) 来计算正确的字体大小。

【讨论】:

  • 但是我应该如何处理这些指标?我有两个对象,具有 (x, y) 位置。我希望它们在任何规模上看起来都完全相同。它适用于几何图元,但不适用于文本。
【解决方案2】:

尝试将RenderingHints.KEY_FRACTIONALMETRICS 也设置为ON Graphics 实例

【讨论】:

  • 很遗憾没有效果
  • 这没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。
  • @AMR 分数指标确实为我解决了这个问题(在没有正确计算字符串长度的情况下可以修复的程度)。看起来像是对我的回答;它显然不适用于 OP 是一个不同的问题。
  • @kiheru 你说得对。它被标记为低质量,它似乎是一个糟糕的答案。也许如果这个答案的作者扩展得更多,它就不会被标记为低质量。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-02
  • 2023-03-12
  • 1970-01-01
  • 2016-02-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多