Using Java to develop cross-platform, fonts scalin

2019-07-16 05:34发布

问题:

I am making some software for my university. A GUI is required. In the first revision of it, I had it use the System Look and Feel (so it would look like a native application within Linux/Mac/Windows). I found this to be cumbersome as I had to make all of my JLabels different sized based on the OS (regardless of resolution/pixel density/etc).

After doing this I was like "okay, I'm NOT going to go through with this again" so I decided to not use the System look and feel and try out Nimbus. It looks nice on the platforms I've tested but the JLabel/JTextField font sizes still don't appear correctly on multiple platforms, regardless of them being specified (as Sans Serif 12). Is there a way I could make the Font truly universal across all platforms and avoid having to do all of this cross-platform testing?

回答1:

As shown here, using an appropriate layout manager and pack() will allow a component to leverage it's preferred size, regardless of platform and font.



回答2:

The problem you are facing is the fact that each platform is independent of each other. From memory (and this is going WAY back now), Java renders it's UI at 72 dpi (this could have changed recently).

You are never going to get the same result from one platform to another. This comes down to the difference in individual platform DPI settings.

This is also the same reason why web pages look different from platform to platform and why many applications look slightly different.

The best you can is careful plan your UIs and make clever use of Swings internal metrics, rather then setting the sizes directly.



回答3:

The main thing you can do is use a specific TrueType font and bundle it as a resource in your application. This way you get the best chance of the font appearing the same on all platforms. There's no guarantee that "sans serif" will be the same on all platforms - Java will just use the closest available match.

You can then load the the font from your .jar at runtime with something like:

InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(filename)
Font font = Font.createFont(Font.TRUETYPE_FONT, is);

As a secondary point, it is always worth designing your app layout so that there is a reasonable amount of flexibility on font size. Maybe you just need to make a bit more space for your JLabels, or have text wrap in certain places etc.