4

I have a Java 7 Swing application developed in Windows XP. I use cross platform look and feel:

UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());

When I run it on linux (Fedora 12). The font is a little wider. So the layout changed in some places due to this.

Is there a way to make the application use the same font or similiar font which come with jre but not local system? then we can make its look and feel really the same.

thanks,

mKorbel
  • 109,525
  • 20
  • 134
  • 319
5YrsLaterDBA
  • 33,370
  • 43
  • 136
  • 210
  • Why not let the layout adjust components to the platform's font metrics? – trashgod Aug 30 '12 at 20:49
  • Yes, it is. That is why the layout changed in some places. If we go opposite, some text/labels will not being displayed properly, I guess. – 5YrsLaterDBA Aug 31 '12 at 12:41
  • what exactly do you want to achieve? To me it sounds like you have an error in the layout and trying to fix that with a standard font - if so or similar, the approach is wrong: fix the layout :-) – kleopatra Aug 31 '12 at 15:39
  • I am trying to make my heavy GUI application's buttons, labels, checkboxes, ... are still displayed properly in Linux. The GUI looks very nice in Windows XP but not in Linux even tne same font is used on top of the crossPlatform look and feel setting. – 5YrsLaterDBA Aug 31 '12 at 16:50
  • repeating: I suspect that the problem is the layout, not the font ... you might consider showing a screenshot and an sscce – kleopatra Aug 31 '12 at 18:04

3 Answers3

4

You could look at UIManager. Swing uses the properties here, such as Label.font, to get default fonts. So you could do:

Font font = // create font
UIManager.put("Label.font", font)

Make sure you change these before any components are created, or you'll get some with the correct font, others without. Here's a program that will show you the default properties that are in the UIManager. Anything ending with .font is what you're looking for.

Another approach would be to create a utility class that will create components with your own defaults:

public class MyComponents {

    public static final Font LABEL_FONT = // create font

    public static JLabel createLabel(String text) {
        JLabel label = new JLabel(text);
        label.setFont(LABEL_FONT);
        return label;
    }
}

If this is a new application without a lot of components, I recommend the second approach. If it's an old application with lots of component generation spread out everywhere, the first approach will be less time-consuming, but still the second approach would probably be better.

Brian
  • 17,079
  • 6
  • 43
  • 66
  • I run that UIManagerDefaults program on my XP and linux. I got the same print out result for default fonts. That means Java uses the same font type but for the same font type Linux and XP render it differently, linux is a little wider than XP. So I have to use a different font on linux to make sure the text/label will not eat more space in Linux? My application is a heavy GUI application. It is a pain. – 5YrsLaterDBA Aug 30 '12 at 20:24
  • Weird. Maybe some font settings are set differently between the different systems? Try setting anti-aliasing using the instructions [here](http://stackoverflow.com/questions/179955/how-do-you-enable-anti-aliasing-in-arbitrary-java-apps). You could also try setting the AA settings to `lcd` as suggested in a [comment](http://stackoverflow.com/questions/179955/how-do-you-enable-anti-aliasing-in-arbitrary-java-apps#comment6740462_4793618) on the same question. – Brian Aug 30 '12 at 21:58
  • as a general rule, you should be very careful with creating arbitrary fonts (assuming that's what you suggesting in the //.... part) : typically users expect something that resembles those used in native apps and OS guidelines require to use those to derive variations (mostly size, not so often style). – kleopatra Aug 31 '12 at 15:43
  • @kleopatra Agreed. `Font.deriveFont` is the best way to create fonts, and should usually be done on the font that's already on the component, i.e. `Font font = UIManager.getFont("Label.font").deriveFont(...);` It depends on your design intent though. If you wanted your program to look consistent across all platforms, you wouldn't use this. If you wanted your program to look consistent with native applications, you would. – Brian Aug 31 '12 at 15:49
  • fair enough :-) Though I suspect the OP isn't really interested in the same font, but in a reasonable Layout across platforms. – kleopatra Aug 31 '12 at 15:54
1

This may not work, but. You could provide your own Font, bundled with the application and load that at Runtime.

Check out Load fonts out of JAR-file and create AWT font (works) and register iText font (does not work) for an example (the answers not quite right, but the intention is good) or http://www.java2s.com/Code/Java/2D-Graphics-GUI/Loadfontfromttffile.htm

Once loaded, you could walk the UIManager's properties, replacing all keys with ".font" in there names to your Font instead.

The problem you are going to face ultimately is the difference in the rendering engines of the OS, including things like DPI and the difference in the Font rendering engines.

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
1

It's not clear whether this is a font problem or a layout problem. Naturally, an sscce would help illustrate what you perceive to be the problem. By contrast, this example illustrates how the layout can adjust to accommodate the default font families on disparate platforms.

As you are using the cross-platform L&F, you might want to turn off bold fonts, as shown here. Instead of using an actual bold font, some platforms derive the bold style from a plain font, often with mixed results.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045