Java (AWT):将文本放入框中

发布于 2024-08-11 22:27:38 字数 2811 浏览 3 评论 0原文

我有一个扩展框架的应用程序。然后,它将使用以下命令显示几行文本:

Font f = new Font("Arial", Font.PLAIN, 10);
g.setFont(f);
g.drawString("Test|great Yes ^.", x, y + 10);

现在发生的情况是文本不适合周围的框。例如,我期望文本适合 [x,y]-[x+width, y+10] (不关心宽度),但它稍微低于 y+10 线。现在,对于大多数字符(“T”、“e”等),这都适合,但是“|”而“g”则不然!它们跌破 y+10 线。看来你不能使用:在 y + characterHeight 处绘制。但什么有效呢?

为了明白我的意思,这里有一些示例代码:

import java.awt.*;

public class test extends Frame
{
        public test()
        {
                /* retrieve max window size */
                GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
                GraphicsDevice[] gs = ge.getScreenDevices();
                GraphicsConfiguration [] gc = gs[0].getConfigurations();
                Rectangle r = gc[0].getBounds();
                setSize(r.width, r.height);
                setVisible(true);
        }

        public void paint(Graphics g)
        {
                final int windowWidth  = getSize().width;
                final int windowHeight = getSize().height;
                g.setColor(Color.BLUE);
                g.fillRect(0, 0, windowWidth, windowHeight);
                g.setColor(Color.WHITE);
                g.fillRect(0, 100, windowWidth, 110);
                int textHeight = 100;
                Font f = new Font("Arial", Font.PLAIN, textHeight);
                g.setFont(f);
                g.setColor(Color.BLACK);
                g.drawString("Test|great Yes ^.", 10, 100 + textHeight);
        }

        public void guiLoop()
        {
                for(;;) { try { Thread.sleep(1000); } catch(Exception e) { } }
        }

        public static void main(String [] args)
        {
                new test().guiLoop();
        }
}

我也尝试了以下代码:

public void paint(Graphics g)
{
        final int windowWidth  = getSize().width;
        final int windowHeight = getSize().height;
        g.setColor(Color.BLUE);
        g.fillRect(0, 0, windowWidth, windowHeight);
        g.setColor(Color.WHITE);
        g.fillRect(0, 100, windowWidth, 110);
        int textHeight = 100;

        String str = "Test|great Yes ^.";
        Font f = new Font("Arial", Font.PLAIN, textHeight);
        Rectangle2D boundingRectangle = f.getStringBounds(str, 0, str.length(), new FontRenderContext(null, false, false));
        f = f.deriveFont((float)(textHeight * (textHeight / boundingRectangle.getHeight())));
        boundingRectangle = f.getStringBounds(str, 0, str.length(), new FontRenderContext(null, false, false));
        g.drawString(str, 10, 100 + (int)boundingRectangle.getHeight());

        g.setFont(f);
        g.setColor(Color.BLACK);
        g.drawString(str, 10, 100 + textHeight);
}

这更好一些:文本较小,因此它可能适合,但仍然存在 y 位置的问题是不正确的。

感谢所有帮助!

I have an application that extends a Frame. Then, it'll display a few lines of text using:

Font f = new Font("Arial", Font.PLAIN, 10);
g.setFont(f);
g.drawString("Test|great Yes ^.", x, y + 10);

Now what happens is that the text doesn't fit in the box around. E.g. I'm expecting the text to fit in [x,y]-[x+width, y+10] (don't care about the width) but it falls somewhat below the y+10 line. Now for most characters ('T', 'e', etc.) this fits but '|' and 'g' don't! They go below the y+10-line. It seems you can't use: draw at y + characterHeight. But what does work?

To see what I mean, here's some sample code:

import java.awt.*;

public class test extends Frame
{
        public test()
        {
                /* retrieve max window size */
                GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
                GraphicsDevice[] gs = ge.getScreenDevices();
                GraphicsConfiguration [] gc = gs[0].getConfigurations();
                Rectangle r = gc[0].getBounds();
                setSize(r.width, r.height);
                setVisible(true);
        }

        public void paint(Graphics g)
        {
                final int windowWidth  = getSize().width;
                final int windowHeight = getSize().height;
                g.setColor(Color.BLUE);
                g.fillRect(0, 0, windowWidth, windowHeight);
                g.setColor(Color.WHITE);
                g.fillRect(0, 100, windowWidth, 110);
                int textHeight = 100;
                Font f = new Font("Arial", Font.PLAIN, textHeight);
                g.setFont(f);
                g.setColor(Color.BLACK);
                g.drawString("Test|great Yes ^.", 10, 100 + textHeight);
        }

        public void guiLoop()
        {
                for(;;) { try { Thread.sleep(1000); } catch(Exception e) { } }
        }

        public static void main(String [] args)
        {
                new test().guiLoop();
        }
}

I tried the following code as well:

public void paint(Graphics g)
{
        final int windowWidth  = getSize().width;
        final int windowHeight = getSize().height;
        g.setColor(Color.BLUE);
        g.fillRect(0, 0, windowWidth, windowHeight);
        g.setColor(Color.WHITE);
        g.fillRect(0, 100, windowWidth, 110);
        int textHeight = 100;

        String str = "Test|great Yes ^.";
        Font f = new Font("Arial", Font.PLAIN, textHeight);
        Rectangle2D boundingRectangle = f.getStringBounds(str, 0, str.length(), new FontRenderContext(null, false, false));
        f = f.deriveFont((float)(textHeight * (textHeight / boundingRectangle.getHeight())));
        boundingRectangle = f.getStringBounds(str, 0, str.length(), new FontRenderContext(null, false, false));
        g.drawString(str, 10, 100 + (int)boundingRectangle.getHeight());

        g.setFont(f);
        g.setColor(Color.BLACK);
        g.drawString(str, 10, 100 + textHeight);
}

This is somewhat better: the text is smaller so it might fit, but there's still the problem that the y-position is incorrect.

All help is appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伴我老 2024-08-18 22:27:38

使用 FontMetrics 怎么样?您可以使用 g.getFontMetrics()Graphics 对象获取它。

比你可以检索最大下降或上升或直接高度(使用getHeight),所以你的实现将是独立于字体的,它应该工作正常..检查文档这里

编辑(解释评论):
没有直接的方法告诉字符串以适合盒子的方式绘制自己。你必须自己做。比如从最大字体大小开始,检查宽度是否适合盒子,否则减小大小并重试。对于高度,您应该首先决定(或获取)最大字体高度,然后您可以设置框应该有多少像素。

What about using FontMetrics? You can obtain it from Graphics object with g.getFontMetrics().

Than you can retrieve max descent or ascent or directly height (using getHeight), so your implementation will be font-indipendent and it should work fine.. check documentation here!

EDIT (to explain comments):
there is no a direct way to tell to a string to draw itself in a manner that can fit a box. You have to do it by yourself.. like start from a max font size and check if width fits the box, otherwise decrement size and try again. For height you should FIRST decide (or obtain) max font height, then you can set how many pixel should the box be.

小嗷兮 2024-08-18 22:27:38

我想我在某种程度上解决了这个问题:

boundingBoxHeight: height of box in which the text should fit
yOffset 从哪里开始绘制字体

            Font f = new Font("Arial", Font.PLAIN, boundingBoxHeight);
            g.setFont(f);
            FontMetrics fm = g.getFontMetrics();
            double shrink = ((double)textHeight / (double)fm.getHeight());
            double newSize = (double)textHeight * shrink;
            double newAsc  = (double)fm.getAscent() * shrink;
            int yOffset = (int)newAsc - fm.getLeading();
            f = f.deriveFont((float)newSize);
            g.setFont(f);

            g.drawString(str, 10, 100 + yOffset);

不过,文本上方有相当多的空白。

I think I solved it somewhat:

boundingBoxHeight: height of box in which the text should fit
yOffset where to start drawing the font

            Font f = new Font("Arial", Font.PLAIN, boundingBoxHeight);
            g.setFont(f);
            FontMetrics fm = g.getFontMetrics();
            double shrink = ((double)textHeight / (double)fm.getHeight());
            double newSize = (double)textHeight * shrink;
            double newAsc  = (double)fm.getAscent() * shrink;
            int yOffset = (int)newAsc - fm.getLeading();
            f = f.deriveFont((float)newSize);
            g.setFont(f);

            g.drawString(str, 10, 100 + yOffset);

There's quite a bit of whitespace above the text though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文