Mac Java tip: How to create Aqua small-sized components

Technologies: Java 5+, Mac OS X 10.5+

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.

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

Big control panel
 
Small control panel
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.

Smaller font on a JList
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.

Shrinking normal components clips them
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:

Smaller component sizes
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:

Smaller tabs
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:

Smaller title bar
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

Web articles and specifications

Comments

Thankyou!

Thankyou!

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options

Nadeau software consulting
Nadeau software consulting