As i was looking through the folder structure of the latest Mustang Update N, a thought occurred to me to look inside the rt.jar. There are some interesting things there, and this entry will look at the class names of Nimbus look and feel.

The Nimbus classes are located in the sun.swing.plaf.nimbus package, and as Jasper already mentioned, most of the code is generated from a designer tool. While the source code of Update N is not yet available, you can still see some quirks of the auto-generated code. Let’s run a simple utility that prints out the top ten list of JRE classes with the longest names:

92:InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedState
91:InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneIconifyButtonWindowNotFocusedState
91:InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowMaximizedState
89:InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneCloseButtonWindowNotFocusedState
88:InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMenuButtonWindowNotFocusedState
78:InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonPainter
77:InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneIconifyButtonPainter
75:InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneCloseButtonPainter
74:InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMenuButtonPainter
61:java_beans_beancontext_BeanContextSupport_PersistenceDelegate

Restricting this list to public classes only (classes with public modifier, which can still be in internal sun packages), we get

78:InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonPainter
77:InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneIconifyButtonPainter
75:InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneCloseButtonPainter
74:InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMenuButtonPainter
53:OptionPaneOptionPaneMessageAreaOptionPaneLabelPainter
45:MemberSubmissionAddressingWSDLParserExtension
40:ContentHandlerAlreadyRegisteredException
40:SQLIntegrityConstraintViolationException
40:SocketFactoryContactInfoListIteratorImpl
39:SpinnerSpinnerFormattedTextFieldPainter

Obviously, the class name length has nothing to do with the functionality itself. It just shows how easy it is to overlook something when you’re auto-generating code.

Going a little back to Mustang update 2, the first list looks like this:

61:java_beans_beancontext_BeanContextSupport_PersistenceDelegate
59:javax_swing_tree_DefaultMutableTreeNode_PersistenceDelegate
52:javax_swing_DefaultComboBoxModel_PersistenceDelegate
50:javax_swing_border_MatteBorder_PersistenceDelegate
48:java_util_AbstractCollection_PersistenceDelegate
48:javax_swing_DefaultListModel_PersistenceDelegate
47:UnsafeQualifiedStaticCharacterFieldAccessorImpl
47:java_awt_GridBagConstraints_PersistenceDelegate
47:java_awt_font_TextAttribute_PersistenceDelegate
46:javax_swing_ToolTipManager_PersistenceDelegate

and the second list looks like this

40:ContentHandlerAlreadyRegisteredException
40:SQLIntegrityConstraintViolationException
40:SocketFactoryContactInfoListIteratorImpl
38:DOM2DTMdefaultNamespaceDeclarationNode
38:FormatFlagsConversionMismatchException
38:TaggedProfileTemplateFactoryFinderImpl
37:Canonicalizer20010315ExclOmitComments
37:Canonicalizer20010315ExclWithComments
37:IEEE754FloatingPointEncodingAlgorithm
37:RelationServiceNotRegisteredException

So, what is your best example of the longest Java class name that you have ever seen? Can anybody beat 92 characters? .NET comes quite close with 86 characters :)

Substance skinning primer

November 6th, 2007

As Substance look-and-feel nears the official release 4.1 (scheduled for November 12th), i’m working on the missing documentation. This entry talks about the using the painter layer to skin custom components.

As mentioned in the painter overview, most of the Substance painting logic is abstracted into a set of painters. This not only allows preventing duplicate painting sequence in the Substance UI delegates. This also provides a painting layer for the applications that wish to paint custom components in a way that is consistent with other Substance visuals.

This applies in two major cases:

  • Providing consistent painting for a standalone component suite, such as SwingX.
  • Providing consistent painting for custom components and visual areas of a specific application.

Instead of trying to match the colors, gradients and animation sequences from the current Substance skin (which might change between various releases), applications can use the Substance painting APIs. This will result in code which is shorter, more maintainable and also produces consistent results.

Skinning primer

The following Substance APIs are most suited for painting custom components:

Most of the Substance UI delegates use a combination of the above APIs. While the exact combination in the existing UI delegates is subject to change in between releases, you can study the core Substance code to see the main combination patterns.

The first pattern is watermark overlaying. The watermarks are painted on most Swing containers, and on some components as well. In simpler cases (such as <font color="darkblue">JPanel</font>), the watermark is painted on top of the gradient fill. In more complex scenarios, after the watermark has been painted, the fill sequence is repeated with lower alpha value. Here is an example of such a scenario:

In this scenario, while the regular controls and containers on the content pane are painted with the regular watermark, the frame header (title pane and tool bar) has less “intrusive” watermark painting. This is achieved by the following sequence:

  • Using the header painter to paint the background gradient.
  • Using the watermark to paint the current watermark.
  • Using the header painter once again, this time with the <font color="darkblue">AlphaComposite.SRC_OVER</font> with alpha value of 0.5.

The second pattern is decorating. The header painters can be used to provide distinct painting to some containers, this setting them “apart” from the rest of the application. As the pattern name implies, this works best on specialized containers and visual areas that are situated along the window edges. Here is an example of SwingX <font color="darkblue">JXLoginDialog</font> component painted by the Substance SwingX plugin:

In this scenario, the <font color="darkblue">JXLoginDialog</font> has a “decoration” strip located along the top side of the window. To paint the background of this component, the custom UI delegate is using the current header painter, which results in a consistent appearance of the top portion of this dialog.Here is another example of this pattern, this time on the <font color="darkblue">JXStatusBar</font> component from SwingX component suite. Assuming that this component will be placed along the bottom side of the frame, the matching UI delegate in the Substance SwingX plugin uses the current header painter to provide a distinct appearance of status bar which is consistent with the title pane and menu bar:

The third pattern is border tracing. Those components that require consistent painting of borders or contours can use the border painter with the matching contour. Here is an example of border tracing in the <font color="darkblue">JRibbon</font> component from Flamingo component suite under the Substance Flamingo plugin:
This UI delegate uses the border painter extensively to create the required visuals. Note the outer contour of the ribbon that also includes the selected tab button, and the inner contours of the ribbon tasks.Here is another example of this pattern, this time on the <font color="darkblue">JCommandButton</font> component from Flamingo component suite. The custom UI delegate uses the border painter to paint the button border (a simpler contour in this case):

The last pattern is gradient filling. It is used to paint the inner fill of custom components (along with the border tracing pattern to paint the component contour). This pattern uses the gradient painter with the matching contour. Here is an example of the <font color="darkblue">JRibbon</font> component from Flamingo component suite:
In this example, the first toggle tab button (Write) is filled by the current gradient painter, providing a consistent appearance with the rest of the application controls. Another example is the previous screenshot (of the <font color="darkblue">JCommandButton</font>), where the button fill is painted by the current gradient painter as well.

Here are some Swing links that you might have missed during this week:

  • Jan Erik Paulsen is working on a new RIA tool named Amanda. Some nice screenshots that use the Titanium look-and-feel that is based on Substance.
  • The release notes for Java 5 on Leopard include a few new client properties that can be used to provide functionality missing from the core Swing components. Examples include indeterminate progress circular indicator, smaller controls and search text fields.
  • Jan Haderka writes about detecting Caps Lock state on the JXLoginPanel SwingX component. This thread on java.net forums has additional comments. The current solution does not sound too robust, and since the correct approach requires using native code (which is currently missing from the JDK), use with care.
  • Eclipse 3.4M3 release notes mention the new API on the Shell component. It allows setting an alpha channel value on supported platforms (see screenshot). While the matching functionality is available in the JNA project for Swing, it’s really time for the core Swing team to provide it in JDK. It’s missing in Tiger, it’s missing in Mustang, and it most probably won’t be in Dolphin (due to major work by the client team on the “Update N” which leaves them with only a few months for Dolphin).
  • Hrish writes about problems with file access in signed applets under IE 7 on Windows Vista. There are some links to MSDN articles, but i think that a more important link would be to Chet’s blog on this subject where he says that “There is an issue worth noting here than cannot be fixed: IE7 on Vista will not let us access the file system outside the IE7 sandbox for applets. This means that even “signed” applets have no permission to write to arbitrary locations on disk. This behavior differs from the old behavior of applets on Windows, but given the restrictions of IE7, there is really no way around the problem.” I’m not sure how this sits along with the user comments on bug 6504236 that say that “there is a well documented design to allow IE add-ins access the file system from the user’s normal (Medium) Integrity level, rather the IE’s Low Integrity level: implement an Internet Explorer Broker Process“.

This week has also seen a few announcements:

  • Mikael Grev has announced release 3.0 of MigLayout project. The main emphasis of this release is on automatic support for resolution independence, which is a very important topic that doesn’t get the attention it deserves (neither in Java world nor elsewhere).
  • David Qiao has announced release 2.2.1 of JIDE component suite. The new components are group list, dual list and aggregate table – all of these are not available in the open-source common layer.
  • Instantiations has announced release 6.5.0 of the WindowBuilder family of products with a few enhancements to the Swing designer.
  • Hans Muller has announced release 1.03 of Swing Application Framework, the reference implementation of JSR 296, while Shannon Hickey has announced release 1.2 and release 1.2.1 of Beans Binding, the reference implementation of JSR 295. There are some breaking changes in the Beans Binding 1.2 (see release notes). While on one hand it is expected from an evolving project which has not been finalized, it brings some interesting questions nonetheless. The first one (this is also relevant for Swing Application Framework) – what exactly do the version numbers signify? Was the release 1.0 just something to “tag” and release so that people will consider it as a production-ready implementation? Or perhaps these are the versions used in NetBeans 6.0 betas – which makes it even worse considering that NetBeans is an IDE and these two projects are JSR reference implementations. And what happens when NetBeans 6.0 is frozen (somewhere this week) and there are still breaking API changes in these two projects?

Overview of Substance painters

November 3rd, 2007

As Substance look-and-feel nears the official release 4.1 (scheduled for November 12th), i’m working on the missing documentation. This entry talks about the painter layer in Substance.

Painter encapsulates a common painting logic. For example, in Substance, selected elements in lists, tables, trees and menus are painted with the same gradients. So, instead of replicating this code across different UI delegates, it is extracted into a common painter. In addition to code reuse, it:

  • Makes it easier to tweak an existing painting sequence.
  • Lets applications to specify a custom (branding) painter which is applied to all relevant controls.
  • Lets applications and third-party developers to provide consistent appearance of custom components without locking themselves to internal implementation details of Substance.

Currently, Substance uses three types of painters which are used on different types of controls and window areas. The core binary bundles a number of painter implementations which are available as externally supported APIs. In addition, Substance provides a plugin layer that allows applications to specify custom painter implementations which are used at runtime to paint existing core and third-party components.

Existing painter types

Currently, Substance uses three different types of painters. These are:

The vasy majority of Substance visuals are painted by using these three painter types (applying the current watermark if necessary). The links above provide more technical information on how to specify custom painters and how to use them to paint custom components and window areas. Applications that wish to provide consistent appearance under different Substance skins are strongly encouraged to use the current runtime painters, even if it results in tying the application code to Substance.