316
|
Chapter 8, Rendering
#63 Add a Third Dimension to Swing
HACK
H A C K
#63
Add a Third Dimension to Swing
Hack #63
User interfaces have stuck to 2D drawing for many years. Today, Swing and
Java3D give you a chance to go one step further and add 3D widgets to your UI.
Have you ever wondered how to add nice 3D components into your Swing
applications? Java3D is a free API provided by Sun Microsystems for Linux
and Windows, and by Apple for Mac OS X, that lets you create 3D scenes.
Although well documented, Java3D seems impossible to use with Swing—at
least at first glance.
The Problems with Java3D
Imagine you decided to create a new, astonishing application called
AmazonPick that would let the user search for books on the Amazon.com
store. Your eye-candy user interface would even display the currently
selected book as a 3D object; whenever the user selects another book, the
3D object would flip to show the new cover on its opposite side. Figure 8-8
shows how the application should look.
Figure 8-8. AmazonPick shows books as full 3D objects
Add a Third Dimension to Swing #63
Chapter 8, Rendering
|
317
HACK
Unfortunately, you won’t be able to obtain these results without a little
imagination. For instance, take a close look at Figure 8-8 and notice the gra-
dient background of the window. Displaying such a background is very easy
with Swing and the opaque properties of Swing components, as seen in the
rather simple class in Example 8-10.
This code creates three buttons, each containing a picture of a book loaded
by the utility class
UIHelper, and then puts them in a JPanel. This panel is
itself added to the content pane of the window, at the south side. With the
help of the
setContentPane( ) method, the default content pane is replaced
by a new panel—an instance of
GradientPanel—that is capable of drawing a
nice gradient. To make sure the gradient remains visible in the buttons
panel, you need to make the panel transparent. This can be achieved easily
by calling
setOpaque(false), which will prevent the component—in our
case, the panel—from drawing its background, letting underlying compo-
nents shine through.
Now, we have to take a slight diversion into AWT and Swing vagaries. With
J2SE, you can use two different graphical toolkits to create an application:
AWT and Swing. The main difference between those two is that AWT wid-
gets are heavyweight whereas Swing widgets are lightweight. These names
Example 8-10. A demo program for 3D components
public BooksDemo( )
{
super("AmazonPick");
JButton cover1 = UIHelper.createButton("", "cover1_small_button", true);
JButton cover2 = UIHelper.createButton("", "cover2_small_button", true);
JButton cover3 = UIHelper.createButton("", "cover3_small_button", true);
JPanel buttons = new JPanel( );
buttons.add(cover1);
buttons.add(cover2);
buttons.add(cover3);
buttons.setOpaque(false);
setContentPane(new GradientPanel( ));
getContentPane().setLayout(new BorderLayout( ));
getContentPane( ).add(buttons, BorderLayout.SOUTH);
pack( );
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
UIHelper.centerOnScreen(this);
}
318
|
Chapter 8, Rendering
#63 Add a Third Dimension to Swing
HACK
come from the very nature of these components. Whatever platform you are
running your application on, AWT widgets are drawn using the underlying
OS native toolkit. Swing, on the contrary, is completely decoupled from the
OS and all the painting is done by Java itself. As a result, AWT widgets are
the least common denominator between the various operating systems sup-
ported by Java. This also means that advanced features like transparency are
pure fantasy with AWT: Swing lets you create transparent components very
easily, but AWT does not.
The bad news is that Java3D offers an AWT component only,
Canvas3D
, to
display a 3D scene. So you’ll have to mix some Swing and AWT code. Here
is how you can add such a component in the Swing UI:
Canvas3D c3d = new Canvas3D(SimpleUniverse.getPreferredConfiguration( ));
c3d.setSize(CANVAS3D_WIDTH, CANVAS3D_HEIGHT);
getContentPane( ).add(centerPanel, BorderLayout.CENTER);
createScene( );
createScene( ) is responsible for building the 3D scene the Canvas3D will dis-
play. Running this code will produce a rather ugly result, as shown in
Figure 8-9.
Figure 8-9. A Canvas3D cannot be made transparent

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.