The default size of Java's Swing components feels large and clunky when building tightly-packed user interfaces for Mac tool palettes, inspectors, ribbons, and info windows. Beneath Swing, however, Apple's Aqua user interface for the Mac includes predefined smaller component sizes designed explicitly for tightly-packed control panels. This article shows how to use Apple's "Mac OS X" look and feel for Java to create these hidden smaller components using Java on a Mac.
Table of Contents
Introduction
The original concept of a menu bar was to place all of an application's features within easy reach at all times. But a menu only supports on/off operations. To support multi-value settings, application's also need sliders, spinners, text fields, combo boxes, and so forth. The trend in today's user interfaces is to put these components within a control panel that, like the menu bar, is always on screen and within easy reach. Apple places these control panels within floating tool palettes and inspector windows, like those in the iWork application suite. Microsoft places similar panels in ribbons, like those in the Office application suite.
Full-sized components make large control panels that take up a lot of precious screen space. Instead, Apple's Aqua user interface provides smaller-sized components and tighter layouts to create smaller control panels that can comfortably sit on screen and still leave room for the main document windows. (See the Controls and View Controls chapters in the Apple Human Interface Guidelines.)
![]() |
![]() |
| Figure 1. Using smaller components and a tighter layout with the "Mac OS X" look and feel creates a smaller control panel. |
Resizing components
Text-based components are easily resized by simply using a smaller font. This works well for JLabel, JTextField, JList, and so forth.
![]() |
| Figure 2. Changing the font size on a JList creates a smaller list. |
In principal, other components support setPreferredSize( ) to make them smaller (or larger). However, Apple's "Mac OS X" look and feel for Java, like many others, implements components using built-in images for buttons, sliders, check boxes, and so forth. If you use a smaller preferred size for these components, they don't get smaller — they just get cropped.
| Figure 3. Changing a component's size crops it when using the "Mac OS X" look and feel. |
Instead, when using the "Mac OS X" look and feel on a Mac you can use special Swing client properties and UI defaults to access Aqua's predefined smaller-sized components. (See Apple's New Control Styles available within J2SE 5.0 on Mac OS X 10.5.)
Setting client properties
Every Swing component has a hash table of client properties that control the component's appearance. To set a client property, call putClientProperty( ) on a component, passing in the property name and value.
component.putClientProperty( name, value );
In most cases, client properties must be set before the component is realized. This is easily done by setting the property after creating the component, but before adding the component to a parent container.
Setting UI defaults
Every look and feel has a hash table of UI defaults that are used to initialize the colors, fonts, icons, borders, and margins of new Swing components. The available defaults differ from one look and feel to another. Apple's "Mac OS X" look and feel includes a few special defaults that enable hidden features not available through the standard Swing API. (See All UI defaults names for common Java look and feels on Windows, Mac OS X, and Linux.)
To set a UI default, call put( ) on the current look and feel's UIDefaults hash table returned by UIManager.getDefaults( ). Once changed, all further components will be initialized using the new default value.
UIDefaults defaults = UIManager.getDefaults( ); defaults.put( name, value );
Using client properties for regular, small, and mini-sized components
To get Apple's small-sized components in the "Mac OS X" look and feel, set a component's "JComponent.sizeVariant" client property to "regular", "small", or "mini".
JButton button = new JButton( "Text" ); button.putClientProperty( "JComponent.sizeVariant", "mini" );
Smaller sizes are available for the principal Swing components, and their subclasses:
![]() |
| Figure 4. The "JComponent.sizeVariant" client property creates smaller component sizes in the "Mac OS X" look and feel. |
Using smaller components may require that you adjust your layout. Since these smaller components are only available on the Mac, if you are writing cross-platform code your application will need to check the name of the platform before doing a Mac-specific layout. (See Apple's Identifying Java on Mac OS X.)
if ( System.getSystemProperty( "os.name" ).toLowerCase( ).startsWith( "mac os x" ) )
{
// On a Mac
}
It isn't necessary to avoid setting client properties on non-Macs. If you set the properties, but run on Windows or Linux with a different look and feel, the Mac-specific client properties are silently ignored.
Using UI defaults for small-sized tabs
To get Apple's small-sized tabs in the "Mac OS X" look and feel, set the UI default "TabbedPane.useSmallLayout" to true before creating a JTabbedPane. Note that you are changing a UI default here, so this value will be used when creating all further tabbed panes. To restore the default, set the value back to false after creating a small tabbed pane.
UIDefaults defaults = UIManager.getDefaults( ); defaults.put( "TabbedPane.useSmallLayout", Boolean.TRUE ); JTabbedPane tabs = new JTabbedPane( );
The smaller tab layout uses a smaller tabs and a smaller tab font:
![]() |
| Figure 5. The "TabbedPane.useSmallLayout" UI default creates smaller tabs in the "Mac OS X" look and feel. |
Using client properties for small-sized window title bars
To get Apple's smaller window title bar for any look and feel, set a window root pane's "Window.style" client property to "small". Normally this is only done for control panel dialogs, but it can be done on any window.
JDialog dialog = new JDialog( parent ); JRootPane root = dialog.getRootPane( ); root.putClientProperty( "Window.style", "small" );
The smaller title bar also has a smaller shadow:
![]() |
| Figure 6. The "Window.style" client property creates a smaller window title bar on the Mac. |
Reducing the size of other components
Swing container components are trivially resizable, such as JPanel, JSplitPane, JToolBar, and JViewPort. They contain nothing that needs to be shrunk down.
As I said above, text-based components are easily resized by using a smaller font. This works for JFormattedTextField, JLabel, JPasswordField, JTextArea, JTextField, and JTextPane. JList, JTable, and JTree resize with smaller fonts too if text is being displayed. If they are displaying icons or components, those need to be resized downward to make the list, table, or tree smaller.
Notably absent from Apple's smaller-sized components feature is JScrollBar (and JScrollPane, which uses it). Currently, there is no way to make a smaller scroll bar. Calling setPreferredSize( ) just crops the scroll bar.
Further reading
Related articles at NadeauSoftware.com
- All UI defaults names for common Java look and feels on Windows, Mac OS X, and Linux surveys the main look and feels and lists all of their UI default names and data types.
Web articles and specifications
- Apple's Human Interface Guidelines goes in to great depth explaining user interface components, layout, and behavior for applications on the Mac.
- Apple's Identifying Java on Mac OS X explains how to get the OS name and JDK version from system properties.
- Apple's New Control Styles available with J2SE 5.0 on Mac OS X 10.5 discusses component client properties to select different button styles, component sizes, and so on.







Thankyou!
Thankyou!
Post new comment