Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Getting average character width in Swing?

843807Mar 19 2010 — edited Mar 26 2010
Hi,

I had the task of converting an AWT custom Table component over to JTable as part of our software updates. Since the old AWT custom grid did all the painting itself and was before SWING i'm running into one particularly challenging issue dealing with font sizes.

The old grid let the user specify the column sizes in character sizes instead of pixels as Swing does. The original author of the table calculated the average character width for a set number of characters and then multiplied that by the number the user entered.
int colWidth = getAveFontWidth(getFont()) * w; // where w is the user specify number of characters (i.e 10)


public static int getAveFontWidth(Font f) {
        FontMetrics fm;

        fm = Toolkit.getDefaultToolkit().getFontMetrics(f);

        return fm.stringWidth("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") / 36;
    }
When i try this same code in JTable as i build my tablecolumnmodel and set the column widths with the code below it doesn't always work like the AWT version.
 int newWidth = getAveFontWidth(getFont()) * w; // where w is the number of characters they want to be able to see in the column
 column.setPreferredWidth(newWidth);
 column.setWidth(newWidth);
I know AWT didn't have Java2D and antialiasing so I'm wondering if that has something to do with it. Also, the fact that JTable now has the complex hierarchy of renderers, etc.
I also am pretty positive that the method above isn't the best to handle unicode chars. The original code was written when we didn't support international charsets (years ago).

I've seen some code on the net and discussions about the complex nature of fonts and sizing so I'm wondering if there a method that can be devised to work better than the one above to get me something closer to the AWT results?

I've tried something like below but it seemed to be the same results..doesn't always work:
public int newGetAveFontWidth(Font f) {
int charWidth = 0;
String input = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!@#$%^&*()- ";
Rectangle2D r = fm.getStringBounds(input, getGraphics());
charWidth = (int) (r.getWidth() / 36);
return charWidth;
}
The other issue I'm dealing with is that Swing automatically appends "..." on the end of a string if it doesn't fit in the space. The customers were wondering if that can be removed, since the AWT version would just remove letters if the text didn't fit. But that's another issue I suppose..my main concern is trying to get the columns sizing more closer to AWT.

P.S> I should mention that we only allow the user to use the following fonts: Dialog, SansSerif, Serif, Monospaced, DialogInput and well allow font styles (BOLD, ITALIC, BOLD_ITALIC, PLAIN)

Edited by: tmulle on Mar 19, 2010 2:12 PM

Edited by: tmulle on Mar 19, 2010 2:23 PM
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Apr 23 2010
Added on Mar 19 2010
8 comments
1,142 views