javaanimationgraphicsfontmetrics

Getting the font metrics before the paint method id called


Hi I am creating a news ticker/ text scroller. I am using the following method:

import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;

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

public class Scroll1 extends JPanel{
    private int x;
    private int x2;
    private int y;
    private String text;
    final int startX=-100;
    public Scroll1(int startX)
    {
        x2=-650;
        x = 20;
        y=150;
        text= "Some Words and others, and now this must be a longer text that takes up the whole panel/ frame for this test to work   ";
    }
    @Override
    public void paint(Graphics g)
    {
        g.setColor(Color.white);
        g.fillRect(0, 0, 400, 300);
        g.setColor(Color.black);
        g.drawString(text, x, y);
        g.drawString(text, x2, y);
        FontMetrics fm= g.getFontMetrics(); 
        System.out.println(fm.stringWidth(text));;
    }

    public void start() throws InterruptedException{
        while(true){
            while(x<= 650){
                x++;
                x2++;
                y = getHeight()/2;
                repaint();
                Thread.sleep(10);
                if(x2>650)
                    x2=-650;
            }

            if(x>=0)
            {
                x=-650; 
            }
        }
    }
    public static void main(String[] args) {
        JFrame frame = new JFrame("Scrolling Panel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Scroll1 scrolling = new Scroll1(-100);

        frame.getContentPane().add(scrolling);
        frame.setSize(400, 300);
        frame.setVisible(true);
        try {
            scrolling.start();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

Basically it has two strings that are being drawn. One starts at the 0 position and the other starts at -650. I got the -650 number by using the font metrics inside of the paint method. The problem is that I had to hard code that number, and if I did a different string that has different metrics, it would not work. I tried making a instance variable called width that stores the font metrics, but it seems that the width is not inputted until the paint method is called. Is there anyway I can get the metrics before it starts drawing it?


Solution

  • Is there anyway I can get the metrics before it starts drawing it?

    Just initialize the variable in the first call to paint (or better yet, paintComponent - see below) - you can do this using a boolean flag, or initialize it's value to an extreme and do a check on the value.

    int x = Integer.MIN_VALUE;
    ...
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        if ( x == Integer.MIN_VALUE ){
            x = -g.getFontMetrics().stringWidth(text);
        }
        ...
    }
    

    Some other tips:

    1. Use a Swing Timer to perform animation, or be sure to dispatch Swing specific calls to the EDT using SwingUtilities.
    2. Don't override paint, rather override paintComponent (and be sure to call the parent method super.paintComponent(g))