eric.m
eric.m

Reputation: 1612

Swing fonts look smaller than they should

I'm working in a Swing program that needs to display text of a given font size. But I've noticed that in Swing, the text looks a lot smaller than it should be. The text is barely readable at small font sizes compared to, for example, Microsoft Word.

Both Swing and Microsoft Word are using Arial, 8. The difference is clear. enter image description here

For those wanting to try, here's a small example:

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(200, 200);
    frame.setLocationRelativeTo(null);

    JLabel label = new JLabel("This is my test text which should look bigger");
    label.setFont(new Font("Arial", Font.PLAIN, 8));

    frame.add(label);

    frame.setVisible(true);
}

Anyone has any idea of what could be going on?

Upvotes: 1

Views: 2988

Answers (3)

Jarlik Stepsto
Jarlik Stepsto

Reputation: 1725

in the java Documentations a Font should get the size in pt but it seems to uses px instead.

So your Text is not 8pt (like in word or libre office, ...) its 8 pixels height. You can convert the pt to px (8pt = ~ 10px)

enter image description here

The exact formula for conversion is not as simple, because its device specific, but you can use (correct for ppi = 96):

pt = px*0.75
px = pt/0.75

This formula is not accurate, but as you can see in my test image: 10/0.75 = = 7.5pt (Size 10 is nearest to the word text)

If you want it as accurate as possible, you can calculate it for your device: a pt is defined as 1/72 in (see wikipedia) so the formula is:

px = pt / (72 / ppi); //ppi = points per inch

In java you can do it as this:

public int pointToPixel(float pt){
   int ppi = Toolkit.getDefaultToolkit().getScreenResolution();
   return (int) Math.round(pt / (72 / ppi));
}

Upvotes: 6

DevilsHnd - 退した
DevilsHnd - 退した

Reputation: 9192

Java tries to accommodate all platforms and it does this quite well but there are some anomalies that will arise which you will need to deal with as a developer. Unfortunately, one such anomaly are font sizes when specifically developing for the Microsoft Windows platform. Most developers don't really care about something like a font size because they want their application to operate under all platforms, just allow the User to modify the font size.

The basic reason why your 8 point font size in Java appears smaller is simply because of a result of the different screen resolution (DPI) assumed by Java 2D and Windows. While Java assumes 72 dpi screen resolution Windows uses 96 dpi or even 120 dpi depending on your font size setting in the Display Properties. Read this for more details.

If you were to run your code example on a MacOS X and compare the displayed text you will most likely find that the font sizes appear identical. You won't on a MS Windows box. So, with all this being said you have some choices to make, either;

1) change the DPI Scaling level (Windows10) in the Windows OS Advanced Display Settings so as to accommodate you application;

2) change your code to accommodate the Windows Operating System if it ever happens to run in one which will definitely be the case. You will therefore need to detect the OS your application is being used in (ie: System.getProperty("os.name");

3) live with it and simply use a font size you're happy with (but do keep in mind that it may look too large on the MS Windows platform).

If you're thinking about choice number 2 then you could do something like this:

A method you can use to convert your Java font size to accommodate a Windows OS platform:

public static double ConvertFontSizeForWindows(double fontSize) {
    // Are we running within a Windows plateform?
    if (System.getProperty("os.name").toLowerCase().contains("windows")) {
        //Yes...so let's convert the font size to accomdate windows.
        int screenRes = Toolkit.getDefaultToolkit().getScreenResolution();
        return (double)Math.round(fontSize * screenRes / 72.0); 
    }
    // No...Just return the original font size.
    return fontSize;
}

This method requires a font size to be supplied as a Double data type and it returns a Double data type since font sizes are not necessarily represented truly as Integers.

And you can use this method within your sample code like this:

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(200, 200);
    frame.setLocationRelativeTo(null);

    JLabel label = new JLabel("This is my test text which should look bigger");
    int convertedFontSize = (int) ConvertFontSizeForWindows(8.0);
    label.setFont(new Font("Arial", Font.PLAIN, convertedFontSize));

    frame.add(label);

    frame.setVisible(true);
}

Upvotes: 5

John Mendoza
John Mendoza

Reputation: 91

When drawing text in Java, the point sizes use pixels, meaning the whole text will fit within 8 pixels vertically, including the bottom of 'y' and 'g's. But in MS Word (which you should be using OpenOffice instead of), the main body of the text is 8 pixels excluding the bottom of letters, making it look bigger. This just seems to be an issue with Swing itself.

Upvotes: 2

Related Questions