Where to put repaint

I am writing a GUI that consists of a JFrame with one JPanel inside its content pane. I want to display monospaced text inside the JPanel. In order to determine what size I require for the JPanel, I need to find out the width and height of a character of that font. In order to do this, I need to get a FontRenderContext object inside the JPanel's paint(Graphics) method. Here is a snippet of my code:

publicclass TextGUIextends JFrame{

privateint numRows;

privateint numCols;

privateint cellHeight;

privateint cellWidth;

private TextPanel panel;

privatestaticfinal Font FONT =new Font("monospaced", Font.PLAIN, 12);

public TextGUI(int numRows,int numCols){

this.numRows = numRows;

this.numCols = numCols;

panel =new TextPanel();

int pWidth = cellWidth * numRows;

int pHeight = cellHeight * numCols;

panel.setPreferredSize(new Dimension(pWidth, pHeight);// ****

}

// ... accessors and methods for printing text ...

class TextPanelextends JPanel{

public TextPanel(){

super();

repaint();// ****

}

publicvoid paint(Graphics g){

if(cellWidth == 0){

FontRenderContext frc = ((Graphics2D)g).getFontRenderContext();

Rectangle2D r = FONT.getStringBounds("X", frc);

LineMetrics lm = FONT.getLineMetrics("X", frc);

cellWidth = (int)r.getWidth();

cellHeight = (int)lm.getAscent() + (int)lm.getDescent();

}

// Now display text...

}

}

}

Everything works except that paint does not seem to be called when I invoke repaint() inside TextPanel's constructor, and thus cell dimensions are not determined. This means that when I set the preferred size of the TextPanel from inside TextGUI's constructor, the dimension used is (0, 0). Do I need to restructure my code, or do I just need to call repaint in a different place? Is there a better way to determine font size information? [In my real code, different fonts are possible]

[3645 byte] By [beethoven_forevera] at [2007-11-27 9:58:21]
# 1

The panel doesn't belong to a parent container when it is created. So I would say invoking repaint() does nothing because the RepaintManager knows the component isn't displayed on the GUI.

A better approach would be to override the getPreferredSize(...) method. When then panel is created you would pass in the rows and columns as parameters and then set the font.. Then in the getPreferredSize() method you can use the Component.getFontMetrics(...) method to get the information you need to calculate the preferred size.

camickra at 2007-7-13 0:29:01 > top of Java-index,Desktop,Core GUI APIs...
# 2
If you use JGoodies Forms as your LayoutManager, you can specify sizes in terms of Dialog Units (DLU's), which automatically scale with the font size.https://forms.dev.java.net/
uncle_alicea at 2007-7-13 0:29:01 > top of Java-index,Desktop,Core GUI APIs...
# 3
Thank you, camickr -- that is certainly better.
beethoven_forevera at 2007-7-13 0:29:01 > top of Java-index,Desktop,Core GUI APIs...