tags:

views:

373

answers:

2

I've never used Java AWT before and now I've got a piece of code that displays a JFrame and sets the font property for all child components to the same value. I'd like to set the property in one place only. How can I do this?

In .NET/WinForms, child controls inherit from their parent controls, thus it would be enough to set the font for the Form instance to have it propagate to all controls. Unexpectedly, this doesn't seem to hold for AWT.

The following little code sets the font for all components recursively:

private void setFontForAll(JFrame f, java.awt.Font font) {
    f.setFont(font);
    setFontRecursive(f.getContentPane().getComponents(), font);
}

private static void setFontRecursive(Component[] components, java.awt.Font font) {
    for (Component c : components) {
        c.setFont(font);
        if (c instanceof java.awt.Container)
            setFontRecursive(((java.awt.Container)c).getComponents(), font);
    }
}

However, it has four drawbacks:

  1. Extra code, which might actually be quite inefficient for large forms with nested layout panels.
  2. Code is non-generic. If I need to do the same for another property in future, I've got to rewrite the method (or refactor it to be more general at the expense of conciseness).
  3. Usage is non-declarative, i.e. has to be called at the very end of the form creation (after all child components have been initialized and added) instead of anywhere in a declarative manner.
  4. It doesn't work. Components are set correctly but not all things are components. For example, the TitledBorders of JPanels don't get set.
+4  A: 

The UIManager class is the thing you need. Before you build your user interface simply tell it what fonts you want. Be warned though; there are a lot of font keys defined and if you want to change them all, you'll have to set them all.

UIManager.put( "Button.font", new Font( "Verdana", Font.BOLD, 12f );
UIManager.put( "Label.font", new Font( "Wingdings", Font.ITALIC, 12f );
// ...etc...

You can see the keys and values that are set by programmatically inspecting UIManager.getDefaults() which returns a hashtable.

banjollity
Thanks, that looks quite versatile.
Konrad Rudolph
+1  A: 

For Swing you can also set the fonts with command-line arguments:

# java -Dswing.plaf.metal.controlFont=Georgia -Dswing.plaf.metal.userFont=Tahoma -jar foo.jar foo.Foo

Add -Dswing.aatext=true for anti-aliasing which makes the whole GUI look a lot nicer. :)

Bombe