SWT Best Practices: Changing Fonts

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

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:

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.

You may also like...

Share this Post

Twitter6
Google+5
LinkedIn
Facebook

Tags

7 Responses to “SWT Best Practices: Changing Fonts”

  1. Maxence says:

    Hello,

    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 :)

  2. Xavier Raynaud says:

    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
    directly.
    ResourceManager handles correct allocation and disposal of resources.

  3. Frank Appel says:

    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.

  4. Moritz Post says:

    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.

  5. @Frank and @Moritz: I’ll agree with you for the standard SWT use case on the Desktop.
    But as soon as you have a different SWT “implementation” like Tabris for mobile devices, there might not be a SystemFont that can be applied to all Buttons, Labels and other Widgets equally. E.g. on iOS the Text(field), Label, Button – all have different font sizes…

  6. Ralf Sternberg says:

    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() );

  7. @Ralf: Thanks. I updated the code in the post

7 responses so far

Written by . Published in Categories: Editors choice, Planet Eclipse

Published:
Feb 10th, 2014
Follow:

Twitter LinkedIn Google+ GitHub