Mac Java tip: How to control window decorations

Technologies: Java 5+, Mac OS X 10.5+

The Mac automatically adds a Mac-style window frame to all Java windows, but there is more that you can do to make sure Java windows look and feel right on a Mac. This article discusses Swing settings and Mac-specific client properties to control the appearance of window decorations on a Mac.

Introduction

Every Java window on a Mac gets a standard shaded title bar, title text, a resize icon, jewel buttons to close, minimize, and zoom the window, and even a drop shadow. These make Java windows indistinguishable from other windows on a Mac. (See the Window Elements and Panels chapters of the Apple Human Interface Guidelines.)

Anatomy of a Mac window
Figure 1. The anatomy of a Java window on a Mac.

All of these window decorations can be controlled from Java, either with AWT or Swing methods or through Mac-specific client properties and runtime options. (See Apple's New Control Styles available with J2SE 5.0 on Mac OS X 10.5.)

Controlling the title bar buttons

AWT Dialog and Frame windows, and Swing JDialog and JFrame windows always have all three jewel title bar buttons. They cannot be removed or all three disabled.

By default, all three buttons are enabled on a frame. Calling setResizable( false ) prevents the frame from being resized by the user. If a frame is not resizable, the Mac disables the green zoom button.

JFrame frame = new JFrame( "Not resizable" );
frame.setResizable( false );
Frame title bar buttons on a Mac
Figure 2. Resizable and non-resizable frame title bars on a Mac.

By default, dialogs enable the red close and green zoom buttons, but disable the orange minimize (iconify) button. If a dialog is not resizable, the green zoom button is also disabled.

JDialog dialog = new JDialog( parent, "Not resizable" );
dialog.setResizable( false );
Dialog title bar buttons on a Mac
Figure 3. Resizable and non-resizable dialog title bars on a Mac.

Setting the title bar text

Frame and dialog title text is always centered on the title bar. The font and color cannot be changed, but the title text can be set on the constructor, or by calling setTitle( ).

JFrame frame = new JFrame( );
frame.setTitle( "Text" );

The Mac supports UTF-8 Unicode characters in window titles. You can use this to show proper characters for the world's languages, or to show equations, dingbats, and other special characters.

Window titles with Unicode characters on a Mac
Figure 4. Unicode characters in window titles on a Mac.

Setting the title bar proxy icon

On a Mac, document windows have a proxy icon to the left of the title text. Users can click and drag the icon to other windows or right-click/command-click to get a path to the document.

To add this proxy icon, get the window's JRootPane and set the Mac-specific "Window.documentFile" client property to a File object. The Mac automatically finds the correct icon for the file or folder. The window title text is not affected. If you want the window title to be the file's name, call setTitle( file.getName( ) ) with the File object.

JFrame frame = new JFrame( file.getName( ) );
JRootPane root = frame.getRootPane( );
root.putClientProperty( "Window.documentFile", file );
File icons on window title bars on a Mac
Figure 5. Frames without and with a file or folder proxy icon on a Mac.

Setting the title bar modified mark

On non-Mac platforms, application's sometimes mark document windows as containing a modified and unsaved document by adding a "*" or other mark to the window's title. On a Mac, the modified-document mark is standardized as a black dot in the center of the red close button on the title bar. The proxy icon, if present, is also dimmed.

To add this mark, get the window's JRootPane and set the Mac-specific "Window.documentModified" client property to true.

JFrame frame = new JFrame( "Modified" );
JRootPane root = frame.getRootPane( );
root.putClientProperty( "Window.documentModified", Boolean.TRUE );
File modified mark on window title bars on a Mac
Figure 6. Frames without and with a modified mark on a Mac.

Unfocusing the title bar

The front window on a Mac has the focus. The Mac draws this window with a shaded gray title bar and red/orange/green jewel buttons. Back windows do not have the focus and are drawn with a light gray title bar and gray jewel buttons.

Calling setFocusableWindowState( false ) marks a window as a floating palette that cannot accept the focus (though its components can). The Mac draws unfocusable windows the same as background windows, giving them a gray title bar and jewel buttons. This is normally only done on dialogs.

If you make an unfocusable dialog modal, you'll confuse users. Such a window is grayed like a background window, but it actually owns the focus and demands a user response.

JDialog dialog = new JDialog( "Not focusable" );
dialog.setResizable( false );
dialog.setFocusableWindowState( false );
Title bar focus on windows on a Mac
Figure 7. Focusable and unfocusable dialogs on a Mac.

Shrinking the title bar

Tool palettes and inspectors can use a smaller window title bar on a Mac. Get the window's JRootPane and set the Mac-specific "Window.style" client property to "small". This is normally only done on dialogs.

The smaller title bar also always has the middle orange button disabled, whether for a frame or dialog, and it has a smaller drop shadow.

JDialog dialog = new JDialog( parent );
JRootPane root = dialog.getRootPane( );
root.putClientProperty( "Window.style", "small" );
Regular and small title bars for windows on a Mac
Figure 8. Regular and small window title bars on a Mac.

Creating a unified title bar

By default, the Mac title bar's shaded gray background is distinct from the solid off-white background of a window. You can blend these together to create a unified look by getting the JRootPane for a window, then setting its Mac-specific "apple.awt.brushMetalLook" client property to true. This property must be set before the frame is realized.

JFrame frame = new JFrame( );
JRootPane root = frame.getRootPane( );
root.putClientProperty( "apple.awt.brushMetalLook", Boolean.TRUE );
Shaded window background on a Mac
Figure 9. Windows without and with the
shaded background on a Mac.

The shaded background automatically changes from a darker gray when the window has the focus, to a lighter gray when it does not.

The same client property can be set as a runtime option passed on the Java command line. This makes all frames, but not dialogs, use the shaded look.

java -Dapple.awt.brushMetalLook="true" myApplication

You can also set this property in the Info.plist file used by the Mac to describe your application.

...
<dict>
    <key>apple.awt.brushMetalLook</key>
    <string>true</string>
</dict>
...

Removing the drop shadow

The Mac window manager adds a soft drop shadow to all windows. The shadow is larger for the front window to help it visually stand out from other windows on the desktop.

To remove a window's shadow, get its JRootPane and set the Mac-specific "Window.shadow" client property to false. This is sometimes useful for temporary splash windows.

JFrame frame = new JFrame( );
JRootPane root = frame.getRootPane( );
root.putClientProperty( "Window.shadow", Boolean.FALSE );
Window shadows on a Mac
Figure 10. Windows with and without a drop shadow on a Mac.

Removing the resize icon

Users can resize a window by a click and drag on the lower right corner of a window. By default, all Mac windows include a resize icon in the corner. To remove this resize icon, disable window resizing by calling setResizable( false ).

frame.setResizable( false );
Frames with and without the resize icon on a Mac
Figure 11. Frames with and without the resize icon on a Mac.

Earlier versions of Java for the Mac also supported a system property to remove the icon. As of Mac OS X 10.5 and its JDK 5 and 6, this feature is now only available as a runtime option passed on the Java command line. It may not be present in future versions of the JDK.

java -Dapple.awt.showGrowBox="false" myApplication

You can also set this property in the Info.plist file used by the Mac to describe your application:

...
<dict>
    <key>apple.awt.showGrowBox</key>
    <string>false</string>
</dict>
...

Removing the title bar

Calling setUndecorated( true ) on a dialog or frame, or creating an instance of a JWindow or Window, creates a window without a title bar or jewel buttons. This is useful for creating temporary splash windows.

JDialog dialog = new JDialog( parent );
dialog.setUndecorated( true );
Undecorated window on a Mac
Figure 12. Undecorated window on a Mac.

Undecorated windows have a smaller drop shadow that does not change when they gain or lose the focus.

Since moving a window on a Mac is done by a click-and-drag on the title bar or bottom bar, if you remove window decorations the window can't be moved normally. Also, without the jewel buttons on the title bar, the window can't be closed, minimized, or zoomed. You will need to implement these features yourself.

Using look-and-feel-specific window decorations

Some Java look and feels can provide their own title bar, icons, and window border. If a look and feel supports this feature, its getSupportsWindowDecorations( ) method will return true.

LookAndFeel laf = UIManager.getLookandFeel( );
if ( laf.getSupportsWindowDecorations( ) )
{
    // Look and feel window decorations are supported
}

Most look and feels do not support this feature. At present, the only major look and feel that does is Sun's "Metal". Apple's "Mac OS X" look and feel does not.

When this feature is supported, frames and dialogs may be marked undecorated and the look and feel asked to add a specific decoration style. The available styles include: NONE, FRAME, PLAIN_DIALOG, INFORMATION_DIALOG, QUESTION_DIALOG, WARNING_DIALOG, ERROR_DIALOG, COLOR_CHOOSER, and FILE_CHOOSER.

JDialog dialog = new JDialog( parent, "Plain" );
dialog.setUndecorated( true );
dialog.setDefaultLookAndFeelDecorated( false );
dialog.getRootPane( ).setWindowDecorationStyle( JDialog.PLAIN_DIALOG );

The NONE style creates an undecorated window. The others add custom window decorations. Here's what they look like for "Metal" on a Mac:

Window decorations by Metal on a Mac
Figure 13. Window decorations from the "Metal" look and feel on a Mac.

This feature should be used with care, if ever. These windows don't look Mac-like and they may confuse users that expect Mac windows on a Mac. One possible use is in a kiosk application where the Mac is hidden from view and only windows like these are shown.

If you try to use any of these with a look and feel that doesn't support them (such as "Mac OS X"), all of the windows will be undecorated.

Further reading

Related articles at NadeauSoftware.com

Web articles and specifications

Comments

The “Hide Toolbar”-Button

Hi,
your articles about Java on Mac OS are great - i found many interesting things i'll adapt for my spplication. Thanks for all the details.
Do you know, whether there's a possibility to dann the Button on the top right of the Titel to a Java Application? That one, that hides the toolbar? Would be great, if there's a possibility to use that button, because i have a Toolbar in my App.

thanks for all the work on your articles

greetings
DarkMoonWolf

Re: The "Hide Toolbar" Button

Unfortunately, I don't know of a way to add the pill-shaped show/hide toolbar button to a Java window's title bar.

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