Results 1 to 7 of 7
  1. #1
    flok is offline Member
    Join Date
    Sep 2009
    Location
    Gouda, the Netherlands
    Posts
    24
    Rep Power
    0

    Default Fitting text in box

    Hi,

    I have an application that extends a Frame. Then, it'll display a few line of text using:
    Java Code:
    Font f = new Font("Arial", Font.PLAIN, 10);
    g.setFont(f);
    g.drawString("Test|great.", x, y + 10);
    Now I would expect that "Test|great." to fit in a box [x,y]-[x + width, y+10] (don't care for the width right now). 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?

    A complete (compiles & runs) example for what I mean:

    Java 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();
            }
    }

  2. #2
    zweibieren is offline Senior Member
    Join Date
    Aug 2009
    Location
    Pittsburgh, PA
    Posts
    284
    Rep Power
    6

    Default

    FontMetrics

    TextLayout

    Here's some code I wrote to get the bounding box of some characters.
    I wanted a font so the string ABCDF would be .6 inches wide for all screen resolutions.

    Java Code:
    	Image offScreen = createImage(100, 200);
    	Graphics2D gOff = (Graphics2D) offScreen.getGraphics();
    	Font bold12 = new Font("SansSerif", Font.BOLD, 12);
    
            TextLayout optTL = new TextLayout("ABCDF", bold12, gOff.getFontRenderContext());
            // width of 5 characters in inches
            float width = optTL.getVisibleAdvance() 
                    / java.awt.Toolkit.getDefaultToolkit().getDefaultToolkit().getScreenResolution();
            // nominally, width in SanSerif,bold,12 is .6 inches
            // so we multiply the font size by .6/width
            tagFont = bold12.deriveFont(12 * 0.6F / width);
            optTL = new TextLayout("ABCDF", tagFont,
                    gOff.getFontRenderContext());
            Rectangle2D bounds = optTL.getBounds();
    If the string had descenders, the bounding box would include them.

  3. #3
    flok is offline Member
    Join Date
    Sep 2009
    Location
    Gouda, the Netherlands
    Posts
    24
    Rep Power
    0

    Default

    Quote Originally Posted by zweibieren View Post
    Here's some code I wrote to get the bounding box of some characters. I wanted a font so the string ABCDF would be .6 inches wide for all screen resolutions. If the string had descenders, the bounding box would include them.
    Yeah most examples I found give you the boundingbox for a given text-size. But none (unfortunately also your example) do the other way around: fit a text in a box.
    The FontMetrics methods for example tell you the width and the height of a string, but not what fontheight you need to use and to plot at what y-coordinate.

  4. #4
    zweibieren is offline Senior Member
    Join Date
    Aug 2009
    Location
    Pittsburgh, PA
    Posts
    284
    Rep Power
    6

    Default

    Here's how:
    Find the bounding box at one font size.
    Compute what font size you need to fit the space you want.
    And then use deriveFont() to get the font that will fit the space.

  5. #5
    flok is offline Member
    Join Date
    Sep 2009
    Location
    Gouda, the Netherlands
    Posts
    24
    Rep Power
    0

    Default

    Quote Originally Posted by zweibieren View Post
    Here's how:
    Find the bounding box at one font size.
    Compute what font size you need to fit the space you want.
    And then use deriveFont() to get the font that will fit the space.
    Something like this then:

    Java 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|gy^";
                    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())));
    
                    g.setFont(f);
                    g.setColor(Color.BLACK);
                    g.drawString(str, 10, 100 + textHeight);
            }
    Looks as if the text is going to fit (it looks somewhat smaller than the height of 100), but where to plot it?

    I tried to do a f.getStringBounds after the deriveFont and then
    Java Code:
    boundingRectangle = f.getStringBounds(str, 0, str.length(), new FontRenderContext(null, false, false));
    g.drawString(str, 10, 100 + (int)boundingRectangle.getHeight());
    but then the text is still below(!) the lower bound.
    Last edited by flok; 11-22-2009 at 07:01 PM. Reason: to clarify what it is i tried

  6. #6
    zweibieren is offline Senior Member
    Join Date
    Aug 2009
    Location
    Pittsburgh, PA
    Posts
    284
    Rep Power
    6

    Default

    From FontRenderContext:
    Typically, instances of FontRenderContext are obtained from a Graphics2D object. A FontRenderContext which is directly constructed will most likely not represent any actual graphics device, and may lead to unexpected or incorrect results.

  7. #7
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,236
    Rep Power
    7

Similar Threads

  1. Replies: 8
    Last Post: 11-06-2009, 07:52 AM
  2. Replies: 2
    Last Post: 01-23-2009, 05:09 PM
  3. printing simple text as text on printer
    By Nicholas Jordan in forum Advanced Java
    Replies: 0
    Last Post: 12-01-2008, 02:42 AM
  4. find and replace text from a text file
    By gezzel in forum New To Java
    Replies: 2
    Last Post: 09-19-2008, 05:04 PM
  5. Replies: 0
    Last Post: 05-26-2008, 05:26 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •