O'Reilly logo

Swing Hacks by Chris Adamson, Joshua Marinacci

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Add Translucence to Menus #12
Chapter 1, Basic JComponents
|
55
HACK
The custom pop-up menu UI used here is similar to the CustomMenuItemUI
(from Example 1-28). It has a static create UI menu and no constructor. The
pop-up menu is already stored as a protected member of the
BasicPopupMenuUI
parent class, so I can access it easily. The
installUI( )
method is called right after the
JPopupMenu
is created, so this is the best place
to put a call to
setOpaque(false)
. For most L&Fs, this will make the compo-
nent transparent.
That takes care of the pop-up menu, but what about the parent
JPanel? The
JPanel
is created and initialized deep within the
javax.swing.PopupFactory
class, so it’s pretty well out of reach. This is one place where having access
to the JRE source code is invaluable. Without that, this entire hack would
have been impossible to figure out. Fortunately, we have access to the fin-
ished
JPopupMenu from within the getPopup method. I overrode that to call
the superclass and then grab the newly minted parent of the pop-up menu
and cast it to a
JPanel. Now, I can finally set it to be transparent, too.
Test It Out
With your two custom UI classes in place, test them out with Example 1-30,
which shows a frame containing two sets of menus and a few components.
Before creating any components, the program installed the custom UI
classes with two calls to
UIManager.put( ).
Any time you want to override part of a L&F, you can use
UIManager.put( ).
Example 1-30. Testing out the translucent menus
public class MenuTest {
public static void main(String[] args) throws Exception {
UIManager.put("PopupMenuUI","CustomPopupMenuUI");
UIManager.put("MenuItemUI","CustomMenuItemUI");
JFrame frame = new JFrame( );
JMenuBar mb = new JMenuBar( );
frame.setJMenuBar(mb);
JMenu menu = new JMenu("File");
mb.add(menu);
menu.add(new JMenuItem("Open"));
menu.add(new JMenuItem("Save"));
menu.add(new JMenuItem("Close"));
menu.add(new JMenuItem("Exit"));
menu = new JMenu("Edit");
mb.add(menu);
56
|
Chapter 1, Basic JComponents
#12 Add Translucence to Menus
HACK
With all of the code in place, you can compile it and get something that
looks like Figure 1-30.
One bug you will notice is that after you open the menu and start moving the
cursor between menu items, the background won’t shine through anymore.
This is because Swing, in an effort to speed up the UI, only repaints the parts
it knows have changed. It repaints the menu item, but not the frame con-
tents below (the button and label, in this case) because it thinks they are
obscured by the menu item. Of course, the menu item is translucent, so the
components should shine through, but Swing doesn’t know that. To fix the
menu.add(new JMenuItem("Cut"));
menu.add(new JMenuItem("Copy"));
menu.add(new JMenuItem("Paste"));
menu.add(new JMenuItem("Paste Special.."));
frame.getContentPane().setLayout(new BorderLayout( ));
frame.getContentPane( ).add("North",new JButton("Button"));
frame.getContentPane( ).add("Center",new JLabel("a label"));
frame.getContentPane( ).add("South",new JCheckBox("checkbox"));
frame.pack( );
frame.setSize(200,150);
frame.show( );
}
}
Figure 1-30. Translucent menu
Example 1-30. Testing out the translucent menus (continued)

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required