Java (AWT): setting text in a field

I have an application that extends Frame. Then it will display several lines of text using:

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

Now it happens that the text does not fit in the field. For example. I expect the text to fit in [x, y] - [x + width, y + 10] (don't care about width), but it falls slightly below the line y + 10. Now for most characters ('T', 'e 'etc.) It works, but' | ' and 'g' is not necessary! They go below the line y + 10. It seems you can not use: draw y + characterHeight. But what works?

To find out what I mean, here is a 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 also tried the following code:

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 can fit, but still the problem is that the y position is incorrect.

All help is appreciated!

+3
2

FontMetrics? Graphics g.getFontMetrics().

( getHeight), , .. !

EDIT ( ): , , . .. , , . ( ) , , .

+4

, :

boundingBoxHeight: , 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);

.

0

Source: https://habr.com/ru/post/1723612/


All Articles