Combo Box Popup
Posted by Rob Camick on November 28, 2010
The standard popup for a JComboBox is displayed below the combo box and is fixed to the actual width of the combo box. In most cases this the desired behaviour as the width of the combo box is determined by the items in the combo box. However there might be times when the combo box is not displayed at its preferred width. In these cases the rendering of the text in the popup may cause some items to be truncated. I’m sure this is not desireable.
Before looking at a solution we need to understand why a combo box might not be displayed at its peferred size. To determine its preferred size the combo box loops through all the items in the model and invokes the renderer to determine the preferred size of each item. The width of the largest item is then used as the preferred width for the combo box. When your combo box contains thousands of items this calculation can be relatively slow. The API gives you an option to bypass this default calculation by using the setPrototypeDisplayValue(…) method. Now only a single calculation is made based on the prototype value. A simple solution, but of course the width is now only a “best guess”. Or maybe you have a dynamic combo box, in which case the addition or removal of items might change the preferred width.
The solution to the problem is to either change the width of the popup dynamically or add a scrollbar to the popup. The BoundsPopupMenuListener is a class that allow you use either of the above solutions or combine the two into a single solution. This custom PopupMenuListener is added to the combo box so the solution should work on any LAF that uses a BasicComboPopup as the popup.
The BoundsPopupMenuListener is a simple class to use. You can set all the properties when the class is created or you can set individual properties after class creation. The properties of the class are:
- setScrollBarRequired – when true, a horizontal scroll bar will automatically be displayed when necessary
- setPopupWider – when true, the width of the popup will be based on the items in the combo box. The width will never be smaller than the combo box.
- setMaximumWidth – can control the width of the popup just in case you have an unreasonably long item to render.
- setPopupAbove – when true the popup will display above the combo box.
You should be able to use the BoundsPopupMenuListener class in any of your applications with just a couple of lines of code. For example to show the popup wider you can use:
BoundsPopupMenuListener listener = new BoundsPopupMenuListener(true, false); comboBox.addPopupMenuListener( listener ); comboBox.setPrototypeDisplayValue("ItemWWW");
Thanks to Jeanette for her answer in this posting which enlightened me on how to override the default size of a popup.
The Swing tutorial doesn’t mention the PopupMenuListener so many people are not aware of this listener. Don’t forget to check out the API to see if this listener might be helpful in other situations as well.
Get The Code
BoundsPopupMenuListener.java
BoundsPopupMenuListenerDemo.java
RelativeLayout.java (needed for demo)
André Uhres said
Another solution is to display tooltips, as shown here:
Cheers,
André
Anonymous said
It does not work in java 1.6.0_25, it worked in 1.6.0_17
Rob Camick said
Thanks for the feedback. I don’t have access to either version so I can’t see what has changed.
Anonymous said
At row 303 of BoundsPopupMenuListener replace
JComboBox comboBox = (JComboBox)popup.getInvoker();
with
JComboBox comboBox = (JComboBox) popup.getAccessibleContext().getAccessibleParent();
Anonymous said
I’ve done the change, but it still does not work on vista & java 1.7.0_02
Alan said
Does not seem to work on windows 2000 with 1.6 u_30 does work on windows 7
Anonymous said
This stpped working somewhere around 1.6.0_24. Here’s an alternative that works with later 1.6.0 release. (I haven’t tried with 1.7).
Anonymous said
lol – forgot the link!
http://www.jroller.com/santhosh/entry/make_jcombobox_popup_wide_enough
Anonymous said
Thx. Figured it out anyway
Anonymous said
Actually am re-writing trading system in jython… amazing how simple the coding is and how reliable the python->java compilier is.
Some minor inheritance gothcas, but get swing and other java libraries for “free” using a powerful scripting language like python.
Anonymous said
Works for me… Thanks…
Anonymous said
Just as a question: If one would want to use the Code since it is quite nice, is this placed under any license, released to the public domain, or is any disclaimer needed?
Anonymous said
Works great, thanks!
Anonymous said
Fine, it’s perfect !
Thanks !
Anonymous said
Works for me, thank you so much
Anonymous said
Thanks you so much, works for me
Eriel Miquilino (Brazil) said
Perfect!
Helped me a lot!
Anonymous said
Eu posso usar em problemas de Copyright?
Hazuka said
thanks bro
Anonymous said
Works fine. Java 7 on Windows 10
EdgarS said
this work to Java 1.4???? or what is the code for java 1.4?
Rob Camick said
I don’t remember what version this was originally tested with. It still appears to work in JDK11 using Windows 10.