SWT Best Practices: Changing Fonts

SWT Best Practices: Changing Fonts

Here is a widespread way of creating a label with a bold font:

<pre lang="java">
Label label = new Label(shell, SWT.NONE);
Font boldFont = new Font( label.getDisplay(), new FontData( "Arial", 12, SWT.BOLD ) );
label.setFont( boldFont );
label.setText("Bold Label");

Everything seems to be fine with this code. A Label is created with the default font “Arial”, the default size “12” and our desired style “BOLD”. So what’s the problem with this snippet?

With the above code that creates a BOLD font, you also specified the font name and size. The problem here is that you might not know which fonts are used on the system that will run your application. A major OS update might introduce new default fonts, and what was once a nice looking application will look like an alien. Or even worse, you want your SWT application to run on other platforms like web browsers or mobile devices that might not have the fonts at all.

So it all boils down to this simple rule: Don’t specify what you don’t want to change!

Here is a better way to do it: in this case it’s like getting the blueprint of the default font, making some changes and building a new font with the modified blueprint:

<pre lang="java">
Label label = new Label(parent, SWT.NONE);
FontDescriptor boldDescriptor = FontDescriptor.createFrom(label.getFont()).setStyle(SWT.BOLD);
Font boldFont = boldDescriptor.createFont(label.getDisplay());
label.setFont( boldFont );
label.setText("Bold Label");

How would you implement a bold label? Do you have another way to deal with font styles? Please let us know in the comments below.

Update (11.02.2014): A blog post about Descriptors and managing SWT resources will follow soon.

  • Maxence
    Posted at 12:23 pm, February 10, 2014


    Just one question I have related to font disposal.
    Indeed, as for Colors, when there is a font you don’t use anymore, you have to dispose it just to ensure there won’t by any graphical/memory issue…

    Using this method, is it something done automatically ? Otherwise, How this should be done ? Should we assign the created font, to dispose it later manually ?

    Thanks a lot in advance 🙂

  • Xavier Raynaud
    Posted at 1:15 pm, February 10, 2014

    An answer to the previous comment:

    It can be good to also use org.eclipse.jface.resource.LocalResourceManager when manipulating fonts, images, colors.

    This class manages SWT resources. It manages reference-counted instances of resources
    such as Fonts, Images, and Colors, and allows them to be accessed using descriptors.
    Everything allocated through the registry should also be disposed through the registry.
    Since the resources are shared and reference counted, they should never be disposed
    ResourceManager handles correct allocation and disposal of resources.

  • Frank Appel
    Posted at 7:26 am, February 11, 2014

    Just thinking aloud: as you mentioned platform independency there might be cases where it could be worth considering Display#getSystemFont() instead of Control#getFont() e.g. if you are not ‘in complete responsibility’ of the control’s lifecycle.

  • Moritz Post
    Posted at 11:16 am, February 12, 2014

    Creating custom fonts from a base font is a good approach. None the less i would agree with Frank: It is good practice to use the Device.getSystemFont() as a baseline since you might not have a widget at hand or the widget might be configured differently for some reason.

  • Ralf Sternberg
    Posted at 12:32 pm, February 13, 2014

    Also on the Desktop, using Display.getSystemFont() may not match the default font used for a certain type of control, because the system may have different defaults for different types of controls. If you set the system font to a control, you might change not only the font style, but also the typeface and the size. The JavaDoc of Device.getSystemFont() explains that “applications which want the default look should simply not set the font on the widgets they create. Widgets are always created with the correct default font for the class of user-interface component they represent.”

    With the approach described in this post, you can be sure that you change only the font style.

    However, the snippet presented here actually does nothing! That’s because FontDescriptor.setHeight() does not modify the actual instance, but it returns a new instance with modified font data. Here’s a working version:

    Font boldFont = FontDescriptor.createFrom( label.getFont() )
    .setStyle( SWT.BOLD )
    .createFont( label.getDisplay() );

Post a Comment