How to resize the width of a JComboBox dropdown list without resizing its edit box ?

You need a JComboBox whose width doesn’t depend on the widest of its items, but you still want the dropdown list to be wider than the JComboBox, wide enough to display properly the widest item. For example :

wider combo box

First, you need to prevent the JComboBox component from eating all the space on screen because of a very long item in its list. Use the
JComboBox.setPrototypeDisplayValue() method (since Java 1.4). For example :

JComboBox myCombo = new JComboBox();
myCombo.setPrototypeDisplayValue("Sample value");

Then, you must ensure the drop down list width matches the one of the widest item. Create a class inheriting JComboBox and override the getSize() method (adapted from Santhosh Kumar’s Weblog):

public class WideDropDownComboBox extends JComboBox {

private static final long serialVersionUID = -2694382778237570550L;
private boolean layingOut = false;
private int dropDownMenuWidth = 0;

// Setting the JComboBox width
public void adjustDropDownMenuWidth() {
dropDownMenuWidth = computeMaxItemWidth();
}

@Override
public Dimension getSize() {
Dimension dim = super.getSize();
if (!layingOut)
dim.width = Math.max(dropDownMenuWidth, dim.width);
return dim;
}

public int computeMaxItemWidth() {

int numOfItems = this.getItemCount();
Font font = this.getFont();
FontMetrics metrics = this.getFontMetrics(font);
int widest = getSize().width; // The drop down menu must not be less wide than the combo box
for (int i = 0; i < numOfItems; i++) {
Object item = this.getItemAt(i);
int lineWidth = metrics.stringWidth(item.toString());
widest = Math.max(widest, lineWidth);
}

int scrollbarWidth = ((Integer) UIManager.get("ScrollBar.width")).intValue();
return widest + scrollbarWidth;
}

@Override
public void doLayout() {
try {
layingOut = true;
super.doLayout();
} finally {
layingOut = false;
}
}
}

Eventually, a sample code :

WideDropDownComboBox myCombo = new WideDropDownComboBox();

myCombo.setPrototypeDisplayValue("Sample value");
myCombo.addItem("Short item");
myCombo.addItem("very very very very very very very very very very very long item");
cbxCompetences.adjustDropDownMenuWidth();

You may hear about a cleaner solution which doesn’t require deriving the JComboBox component, but uses a PopupMenuListener and the event popupMenuWillBecomeVisible to resize the drop down list on the fly. I would prefer it, unfortunately, this solution was broken in JAVA runtime 1.0.6_26-b03 (as reported here).

Leave a Reply

Your email address will not be published. Required fields are marked *