1

I have an application where I need to change font sizes frequently. A question posted a year ago on this forum (Change just the font size in SWT) gave me some of the information I needed, but I've still got some unknowns I haven't figured out yet.

In particular, someone signing as hudsonb offered a helpful code fragment which I'd like to reproduce below:

FontData[] fontData = label.getFont().getFontData();
for(int i = 0; i < fontData.length; ++i)
    fontData[i].setHeight(14);

final Font newFont = new Font(display, fontData);
label.setFont(newFont);

// Since you created the font, you must dispose it
label.addDisposeListener(new DisposeListener() {
    public void widgetDisposed(DisposeEvent e) {
        newFont.dispose(image);
    }
});

Suppose I used code like this to change font sizes frequently. Aren't I creating a whole sequence of DisposeListeners, and adding them to the label's listener queue? Don't I need to remove the previous listener each time before adding a new listener? Or is there some mechanism I don't understand that makes this unnecessary?

Community
  • 1
  • 1
vw-register
  • 214
  • 4
  • 10

3 Answers3

0

You probably should remove the old listeners. Do this with:

private DisposeListener listener = null;
//...
if (listener != null)
    label.removeDisposeListener(listener);
listener = new DisposeListener() {
    public void widgetDisposed(DisposeEvent e) {
        newFont.dispose(image);
    }
}
label.addDisposeListener(listener);
Peter C
  • 6,219
  • 1
  • 25
  • 37
  • Yes, this is what I was wondering if I needed to do. Since the new listener is created at a distant place and time in the code, to do this I would need to preserve a handle to the previous listener such that it can be available at the disposal point. I can do that, but it's a lot of work, and I'm trying to find out if it's necessary. Your vote is: probably yes? – vw-register Nov 05 '10 at 23:19
  • Yeah. I was trying to think of a better way around it, but this seems like the simplest. – Peter C Nov 05 '10 at 23:26
0

An alternative would be to add a DisposeListener that maintains a list of Fonts it needs to dispose of when finished with, e.g.

class FontDisposer implements DisposeListener {
    private List<Font> toDispose;

    public FontDisposer() {
        toDispose = new ArrayList<Font>();
    }

    @Override
    public void widgetDisposed(DisposeEvent e) {
            // Dispose all fonts in toDispose
    }

    public void registerFont(Font f) {
        toDispose.add(f);
    }
}

class UIWotsit extends SomeUIClass {
    private FontDisposer disposer;

    public UIWotsit() {
        disposer = new FontDisposer();
        addDisposeListener(disposer);
    }

    public void changeFont(Font f) {
        disposer.registerFont(f);
        // Do all the font changing stuff
    }
}

This may not suit your particular application but having something that maintains a list of Fonts is probably a reasonable start. You could also use an anonymous DisposeListener that calls a method in whatever code manages the Font creation/changing/disposal:

class OtherFontDisposer implements DisposeListener {
    @Override
    public void widgetDisposed(DisposeEvent e) {
        myCleverFontManager.disposeOfAll();
    }
}

It all depends on whether you are creating new labels or not, and whether you want to dispose of Fonts immediately or only when the UI is disposed of.

Cameron Skinner
  • 51,692
  • 2
  • 65
  • 86
0

If you change your font size often, you'll probably also change back to sizes, that you've already used. So you might want to cache your Font instances. To do so, you can use the FontRegistry from JFace (JavaDoc) instead of a list. You won't need to dispose the Fonts, as this is done by the registry when your Display is disposed.

You still have to put your FontData into the registry if it doesn't contain the size you need yet.

the.duckman
  • 6,376
  • 3
  • 23
  • 21