Turn Dialogs into Frame-Anchored Sheets #44
Chapter 6, Transparent and Animated Windows
|
229
HACK
A sheet doesn’t have a close box
Dialog close boxes are one of the most hateful and stupid concepts in
Windows and its many Linux imitators. What does the close box mean?
Cancel? The default option? What does it mean when the dialog has
multiple options of equal plausibility and thus no default? Perhaps the
worst thing about the close box was back in the AWT era when Java
developers—too lazy to add and wire-up an OK button to their dia-
logs—just figured users could dismiss the dialog with the close box.
Mac OS 8 and 9 dialogs didn’t have close boxes, so when a Java applica-
tion brought up such a dialog, the application blocked itself forever. Duh.
Sheets mean having to click one of the provided buttons, so the user’s
choices are unambiguous.
A sheet is used to block one window
This is an obvious side effect of being visually tied to a single window,
but that’s probably the most common case. As a side effect, this gives
greater prominence to dialogs that block all windows for a single appli-
cation (“Are you sure you want to Quit and lose all unsaved changes in
all documents?”) and dialogs that block all applications (“Are you sure
you want to Shut Down?”).
So, if you agree that it’s an excellent GUI concept, the next question is “how
do I mimic sheets in Swing?”
Use the Glass Pane
One way to imitate the Mac OS X sheet is to use the glass pane—a layer in
the
LayeredPane used by all RootPaneContainers, including JApplets, JFrames,
JInternalFrames, JWindows, and JDialogs. In terms of z-order—the ordering
of layers on “top” of one another from the user’s perspective—the glass
pane is “above” the content pane and the menu bar in the
LayeredPane. It is
Figure 6-7. Sheet in Mac OS X Safari browser
230
|
Chapter 6, Transparent and Animated Windows
#44 Turn Dialogs into Frame-Anchored Sheets
HACK
usually empty and unfilled. One of the more typical uses for the glass pane is
to add a
MouseListener and MouseMotionListener to deny events to the con-
tent pane and thereby block it.
To imitate the sheet with the glass pane, the idea is to take the contents
you’d usually put into a
JDialog
and place them instead into the glass pane.
This will put them in the frame, above and in front of the frame’s contents.
To position your contents at the top center of the glass pane, you can use a
GridBagLayout that gives the sheet a NORTH anchor, and then add a “glue”
component in the next row that takes up as much vertical space as possible,
pushing the sheet to the top of the pane.
Example 6-7 shows a subclass of
JFrame that exposes a showJDialogAsSheet( )
method, which grabs the JDialog’s content pane JComponent and inserts it
into the glass pane as the sheet.
Example 6-7. Adding a sheet in a JFrame’s glass pane
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
public class SheetableJFrame extends JFrame {
JComponent sheet;
JPanel glass;
public SheetableJFrame (String name) {
super(name);
glass = (JPanel) getGlassPane( );
}
public JComponent showJDialogAsSheet (JDialog dialog) {
sheet = (JComponent) dialog.getContentPane( );
sheet.setBackground (Color.red);
glass.setLayout (new GridBagLayout( ));
sheet.setBorder (new LineBorder(Color.black, 1));
glass.removeAll( );
GridBagConstraints gbc = new GridBagConstraints( );
gbc.anchor = GridBagConstraints.NORTH;
glass.add (sheet, gbc);
gbc.gridy=1;
gbc.weighty = Integer.MAX_VALUE;
glass.add (Box.createGlue( ), gbc);
glass.setVisible(true);
return sheet;
}

Get Swing Hacks now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.