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.