Following my entries on platform-specific font policies for Mac and Gnome, one of Substance users stepped up and provided an implementation that makes all Substance-powered Swing application pick the correct font sizes when running under the KDE desktop.
Here is a screenshot of a test application running under KDE desktop with font size of 10 and DPI set to 96:

and here is the same application, running under 120DPI, using font size of 10 except for menus which are configured to use italic 8:

The current implementation can be found in the CVS repository and was contributed by Paranoid (many thanks). It parses a few configuration files to get the DPI and font settings, providing fallback values in case these can not be found. Give the latest 4.2dev drop a try and let us know if you’re having any problems on KDE desktop.
The threading rules in Swing are one of the main reasons for the perceived slowness of Java desktop applications (it remains to be seen whether JavaFX will address this issue for anything other than toy demo applications that have started appearing lately). This article by John Zukowski is an excellent overview of the threading rules in Swing since its inception, and how to write applications that do not break the thread safety.
All different EDT-related rules pretty much boil down to one simple thing – anything that affects pixels on the screen should be done on EDT. However, these rules are all concerned about the where and not the when. And the when is very important. Here is the rule all Swing applications should abide by:
Event listener logic that affects pixels on the screen should schedule its execution after the current event has been processed by all registered event listeners.
The reason for doing this is simple – your application listener is not the only one that is registered for that specific event type. You might think that it’s the only one – after all, you know your application code inside out. However, there is much more going on “under the hood”, and that depends on the look-and-feel you’re using.
The look-and-feel doesn’t have any magic way of tracking the application state. Since the UI delegates use the same event / listener mechanism to track changes to control models, they rightfully expect the application logic to not interfere with the component state while the current change is being processed.
A simple example – application logic registers an action listener on a button. The action listener logic changes the UI state of the application (transitions to the next screen of the wizard, for example) and hides this button. After this action listener is done, the next action listener is called. What does it see? Surprise surprise – the button is no longer in the same state as it was when it was actually pressed.
The solution is very simple – wrap your action listener logic in SwingUtilities.invokeLater. I know, it makes the code ugly. I know, it makes the code go so much to the right side of your editor that you start hating Swing and contemplate switching to VB. But it is simply the right thing to do. You wouldn’t want any other listener to do that to the event source component, so why are you doing it yourself?
Two weeks ago i wrote about the first drop of Bramble plugin for Substance look-and-feel, which provides support for native text rendering in Swing applications. Today, it’s time to look at the actual implementation and see how it all works together.
Unlike SWT that passes the painting requests to the underlying native APIs, Swing handles all the painting itself (unless we’re talking about Windows and GTK look-and-feels under Mustang, which have their own set of problems). Swing’s greatest flexibility is in its “layered” approach to rendering the components (see this PDF presentation that shows one of the possible effects that are extremely easy to achieve with Swing UI delegates). Take, for example, painting a button. It’s all done in independent layers which are then composited together using the powerful Java2D APIs:
- Background
- Icon
- Text
- Focus
- Border
What happens when you want to provide custom rendering for one of these layers (text in our case)? Just override the relevant paint method and provide the logic there (not touching any other pixels). Seems easy, but since SWT has its own painting model dictated by the OS, it’s not. The main difference between text rendering in AWT / Java2D and SWT is that the later expects the background pixels to be fully specified (as detailed in this discussion on the platform-swt-dev mailing list and this discussion on the eclipse.swt.forum).
And as it turns out, this complicates the logic of plugging the SWT text rendering into the Swing painting pipeline, but the end result is most certainly worth it. I’ve already posted a few screenshots, and here is one more:

The first two rows (labels and text fields) are rendered by Swing (Vista + Mustang), while the last two rows are rendered by SWT / native code. While for labels the difference might not be that big, for the digits it is simply staggering (at least for the default Vista Segoe UI font). So, what do we have to do in order to have the native text rendering in Swing?
The current implementation has three stages:
- Filling the component bounds with the background color. The actual color depends on the component kind and component opacity (can come from the parent container).
- Painting all the overlay / highlight layers. List cells have rollover / selection highlights. Text components have multiple highlights depending on the text selection mode.
- Painting all the texts. There can be more than one with different fonts and colors. Menus have the menu text and accelerator text. Sliders have multiple labels. Text components have multiple selected and unselected sections.
The pure Swing implementation doesn’t have to be concerned with combining the results of these three stages together, since Java2D’s drawString method can operate on a translucent / transparent image (with questionable results in some cases, or otherwise there would be no need for this entry). The native text rendering expects all the background pixels to be filled before it can paint the text. Depending on the actual component, this can make the nice and structured Swing UI delegate implementation a little bit more coupled. This is especially true for such complex components as lists, trees, tables, combo boxes, sliders and all types of text components.
In addition to this limitation, there are technical issues with integrating Java2D and SWT rendering. What is the flow here?
- Java2D code paints the component background and overlay / highlight layers on an AWT image
- An SWT image is created from the pixels of the AWT image
- AWT font and color settings are use to create the matching SWT text layout
- SWT text layout is used to paint the text on the SWT image
- Another AWT image is created from the pixels of the SWT image (which at this point contains the background, overlay / highlight layers and the texts)
- This AWT image is painted back on the Java2D Graphics that is passed to the UI delegate
All these steps might add significant overhead to the overall painting performance, especially considering that text elements are pretty much everywhere in a common UI. The first drop that was available two weeks ago had some big performance issues on large lists and tables. This has been addressed by clipping the compositing area to only the necessary rectangle. In addition, there are minor differences between the two UI toolkits. For example, AWT uses pixels and SWT uses points. This means that the font size needs to be converted to maintain the visual results. In addition, most SWT resources need to be explicitly disposed (much like Java’s streams, for example, that need to be explicitly closed).
The components that are supported in the latest drop of Bramble plugin:
- Buttons, toggle buttons, check boxes and radio buttons
- All menu elements, including menus and menu items
- Tabbed panes
- Labels including the default cell renderers for trees, tables, lists and uneditable combo boxes
- Text fields and formatted text fields with simple documents, including default editors for editable combo boxes
- Decorated title panes for frames, dialogs, internal frames and desktop icons
- Slider labels
- Table headers
- Tooltips
- Components from the Flamingo component suite such as command buttons and ribbon
If you’re interested in testing this implementation, you need to do the following:
- Download the substance-bramble.jar here and add it to the classpath of your application.
- Add the org.eclipse.swt.win32 jar to the classpath of your application. Bramble distribution bundles this jar from Eclipse 3.2.1 in the ‘lib’ folder.
- Extract the matching swt-win32.dll and add it to the java.library.path of your runtime configuration. Bramble distribution bundles this DLL from Eclipse 3.2.1 in the ‘lib’ folder.
- Configure your application to run under the latest 4.2dev drop of Substance look and feel.
If you run into any issues with components mentioned above or custom cell renderers / editors, i would be more than interested hearing about it. The plugin is distributed under the Eclipse Public License (EPL).
Working on an enhancement request to disable spinner buttons when the model returns null value (for either previous or next values), i stumbled across the following new undocumented property that can be set on UIManager in Mustang – “Spinner.disableOnBoundaryValues”
When you set it to Boolean.TRUE, some core look-and-feels (such as Metal in the screenshot below) will disable spinner buttons according to the model state. Note the down button of the first spinner that is disabled since the current shown value is the first value in the model (and there is no previous value to go to):

A quick search on Google reveals that this property is not documented anywhere except the source code for BasicSpinnerUI class, which begs the question – why add it at all if you’re not documenting it? Will it be supported in Dolphin and further, or is it just an internal implementation detail that can go away at any time?