Geertjan is a DZone Zone Leader and has posted 466 posts at DZone. You can read more from them at their website. View Full User Profile

Drop Down Buttons in Swing: A New Alternative

03.05.2008
| 39387 views |
  • submit to reddit
The literature on Drop Down Buttons in Swing, as this search of Google reveals, is not extensive. And what there is is dated. Here I give a brief overview of the existing resources and... provide a completely new and undocumented alternative that has existed since almost one year ago.

The best survey I have found on the status of Drop Down Buttons in Swing is The Ubiquitous Drop Down Button - Swing Style, on the Mammoth Software site. The author discusses the approach taken by Santhosh Kumar and another approach taken by the PSP (Personal Software Process) Dashboard. Problems across look and feels are identified and the consequences of extending the Box class instead of the JButton class are highlighted, among other areas. Then the Mammoth Software Drop Down Button is presented, requiring a certain amount of coding, because the solution is built from the ground up, which also has its advantages, such as the fact that you have a lot more control than if you were using someone's library.

However, let's look at a different approach. Irrespective of the question of which one is better/worse, it's at least useful knowing that this one is out there too. A NetBeans API changes log dating from May 4, 2007, says the following, in its typical lowkey tone of voice: "Added a factory class that can create special buttons with a small arrow icon that brings up a popup menu when clicked."

At least an exclamation mark would have been justified! Here, before I show the code, is the result in a simple sample application:

That's what one would expect a Drop Down Button to do, right? Well, there it is. In fact, it is one of the very many hidden features of the NetBeans Platform. But you can forget the NetBeans Platform (as well as NetBeans IDE). Both of these are irrelevant to this story, neither are needed, just one single JAR file from the NetBeans IDE distribution. In the same way as you can reuse the NetBeans Visual Library API in your own Java applications (i.e., outside of the NetBeans Platform), you can also take the NetBeans UI Utilities API (platform7/modules/org-openide-awt.jar in any distribution of NetBeans IDE) and simply make it available to your own application.

Once you've done that, life is good, you can use the org.openide.awt.DropDownButtonFactory class:

//declarations:
private static JButton dropDownButton;
private static JPopupMenu popup;
private MyMenuItemListener menuItemListener;

...
...
...
//constructor:
public DemoJFrame() {

//create JFrame, add JMenuBar,
//together with some JMenus and JMenuItems:
initComponents();

//initialize JPopupMenu:
popup = new JPopupMenu();

//initialize ActionListener:
menuItemListener = new MyMenuItemListener();

//declare array of names:
String[] names = {"John", "Paul", "Ringo", "George"};

//iterate through the names,
//create JMenuItem from each,
//set name and add ActionListener,
//and then add to JPopupMenu:
for (int i = 0; i < names.length; i++) {
String name = names[i];
JMenuItem item = new JMenuItem(name);
item.setName(name);
item.addActionListener(menuItemListener);
popup.add(item);
}

//use the org.openide.awt.DropDownButtonFactory to create a DropDownButton,
//define the icon and then assign our JPopupMenu to the JButton:
dropDownButton = DropDownButtonFactory.createDropDownButton(
new ImageIcon(new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB)),
popup);

//the JButton will be quite long by default,
//let's trim it by removing borders:
dropDownButton.setBorder(javax.swing.BorderFactory.
createEmptyBorder(1, 1, 1, 1));

//set the icon:
dropDownButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/demo/copy.gif")));

//add the JButton to the menu bar:
mainMenuBar.add(dropDownButton);

}
...
...
...

I am curious to know what other Swing developers think of this solution. One thing I need to do is show the result under different look and feels, as the article mentioned in the introduction did. Other than that, it's great how this solution integrates so closely with existing JButtons and JMenuItems and simply repurposes them so effectively.

 

 

 

Published at DZone with permission of its author, Geertjan Wielenga.

Comments

Richard Osbaldeston replied on Wed, 2008/03/05 - 10:02am

Why create the button via the factory with an empty ImageIcon and then later set the Icon manually? Were you just showing it could be done? The other thing that strikes me is the use of a factory, is that nessecary? While I like ComponentFactories myself they don't play nice with GUI builders. Having Netbeans components that can't be used as beans in the Netbeans Pallete seems like shooting yourself in the foot. Why don't they publish a library for the pallette if they'd like more people using them?

Don't understand this step myself (I still import from jars) but I know the swingx guys have been trying to achive this with builds after 0.9.2. Not that Netbeans always plays nice with SwingX either because of the classloader behviour conflicting with SwingXs ComponentAddons ref: http://www.netbeans.org/issues/show_bug.cgi?id=127881 .

Oh, and theres a couple of DropButtons in the swingx incubator too.. Theres a DropButton and a SplitButton hidden in there somewhere. Split works a little differently though, the button is divided into two distinct actions one for the arrow (shows dropdown) and one for the button action (button type selected from drop down). Works like the PhotoShop palette tools.

Geertjan Wielenga replied on Wed, 2008/03/05 - 10:07am

Hi Richard. I agree with you -- would be better if it was a bean instead of a factory. I have a feeling it originally wasn't intended to be used externally, the way I am doing here, so no thought was given to someone wanting to drag and drop it from the palette. Thanks for the info on those SwingX incubator components.

Kirill Grouchnikov replied on Wed, 2008/03/05 - 11:37am

You might want to take a look at command button component in Flamingo project. It offers capabilities of drop down button and much more. It also extends the AbstractButton so you get all the usual behavior, and it looks well under existing core and third-party look-and-feels.

Patrick Gotthardt replied on Wed, 2008/03/05 - 11:56am

Jidesoft also offers a free split button component (its part of our jide-common project at java.net). Well tested, heavily used. Certainly not a bad idea to use that one.

Adding the feature from the outside isn't a bad idea though. I have published a blog entry about this (using a custom border for the arrow icon) a couple of years ago and used the same approach to develop a JTextField with icons/dropdown capabilities. But still, I'd suggest using Jides (not just because I work for them, but also because it's well tested and supported). 

Andres Almiray replied on Wed, 2008/03/05 - 1:42pm in response to: Patrick Gotthardt

Patrick, you beat to mention Jide JCL =-), on the other hand Groovy has a companion to SwingBuilder that can handle Jide components: JideBuilder. So you'll be able to code UIs faster and still have access to third party Swing components.

Fabrizio Giudici replied on Wed, 2008/03/05 - 1:55pm

I think that BlogOfBug also has a JXDropButton - but at the moment his site is not working, so I can't check. In any case, the DropDownButtonFactory is interesting, as I need it in the RCP platform, I'll try it.

Desmond Kirrane replied on Fri, 2009/06/19 - 7:49am

 Hi Geertjan,

Just found this GREAT post! and need some help.

I am creating a NetBeans Plugin and would like to use this button. My problem is: How can I add this to my existing GUI that was created with The GUI Builder (Matisse). I can't edit the code as itr was generated by the GUI Builder.

Is there a way to add this to the Matisse Palette in NetBeans?

 

Desmond Kirrane replied on Fri, 2009/06/19 - 8:01am

By the way. What NetBeans IDE class is used to create the other buttons in the GUI you have shown e.g the scissors button.

prasad de zoysa replied on Fri, 2009/07/31 - 1:24am

hello sir,

 

can you send me a complete sample code please... i need in immediatly..

prasaddev.

Ram Venkat replied on Mon, 2010/02/22 - 1:24am

Hai I am new to java. please send the entire code to create the splitButton. I need it now.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.