这个不知道有没有人写过.
有点限制, 因为替换了UI, 所以只能在Metal下看才不会有异样的感觉.
import java.awt.Dimension;
import java.util.Vector;
import javax.swing.ComboBoxModel;
import javax.swing.JComboBox;

/** *//**
* Created at 2006-7-25 13:06:10<br>
* 下拉延长的下拉框
*/
@SuppressWarnings("serial")

public class ExtendedComboBox extends JComboBox ...{

public ExtendedComboBox() ...{
}

/** *//**
* @param aModel
*/

public ExtendedComboBox(ComboBoxModel aModel) ...{
super(aModel);
}

/** *//**
* @param items
*/

public ExtendedComboBox(Object[] items) ...{
super(items);
}

/** *//**
* @param items
*/

public ExtendedComboBox(Vector<?> items) ...{
super(items);
}

/** *//**
* (非 Javadoc)
*
* @see javax.swing.JComboBox#updateUI()
*/
@Override

public void updateUI() ...{
setUI(new ExtendedComboBoxUI());
}

/** *//**
* (非 Javadoc)<br>
* 如果需要修改最适合尺寸, 重写此方法
*
* @see javax.swing.JComponent#getPreferredSize()
*/
@Override

public Dimension getPreferredSize() ...{
Dimension dim = super.getPreferredSize();
dim.width = 120;
return dim;
}
}
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.plaf.metal.MetalComboBoxUI;

/** *//**
* Created at 2006-7-25 13:09:13<br>
* 延长的ComboBoxUI
*/

public class ExtendedComboBoxUI extends MetalComboBoxUI ...{

public static ComponentUI createUI(JComponent c) ...{
return new ExtendedComboBoxUI();
}

/** *//**
* (非 Javadoc)
*
* @see javax.swing.plaf.basic.BasicComboBoxUI#createPopup()
*/

protected ComboPopup createPopup() ...{
ExtendedComboPopup popup = new ExtendedComboPopup(comboBox);
popup.getAccessibleContext().setAccessibleParent(comboBox);
return popup;
}

public ComboPopup getPopup() ...{
return popup;
}
}
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.JComboBox;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ScrollPaneConstants;
import javax.swing.plaf.basic.BasicComboPopup;

/** *//**
* Created at 2006-7-25 13:07:04<br>
* 延长的下拉框弹出菜单
*/
@SuppressWarnings("serial")

public class ExtendedComboPopup extends BasicComboPopup ...{
private int width = -1;
private int maxWidth = 300;

/** *//**
* @param combo
*/

public ExtendedComboPopup(JComboBox combo) ...{
super(combo);
}

/** *//**
* (非 Javadoc)
*
* @see javax.swing.plaf.basic.BasicComboPopup#createScroller()
*/

protected JScrollPane createScroller() ...{
return new JScrollPane(list, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}

/** *//**
* (非 Javadoc)
*
* @see java.awt.Component#show()
*/
@SuppressWarnings("deprecation")

public void show() ...{
// todo: if not set the width of popup menu,
// then set the default width(width of combobox)
Dimension popupSize = comboBox.getSize();
Insets insets = getInsets();
popupSize.setSize(popupSize.width - (insets.right + insets.left),
getPopupHeightForRowCount(comboBox.getMaximumRowCount()));
// 计算最大项目的宽度
int maxWidthOfCell = calcPreferredWidth();
width = maxWidthOfCell;
if (width > this.maxWidth)
width = this.maxWidth;
if (width < this.comboBox.getWidth())
width = comboBox.getWidth();

if (maxWidthOfCell > width) ...{
// 显示竖滚动条
// 需要增加高度
popupSize.height += scroller.getHorizontalScrollBar().getPreferredSize().height;
}
Rectangle popupBounds = computePopupBounds(0, comboBox.getBounds().height, width,
popupSize.height);
scroller.setMaximumSize(popupBounds.getSize());
scroller.setPreferredSize(popupBounds.getSize());
scroller.setMinimumSize(popupBounds.getSize());
list.invalidate();
syncListSelectionWithComboBoxSelection();
list.ensureIndexIsVisible(list.getSelectedIndex());
setLightWeightPopupEnabled(comboBox.isLightWeightPopupEnabled());
show(comboBox, popupBounds.x, popupBounds.y);
}

/** *//**
* 计算当前的最适合宽度
*
* @return
*/

private int calcPreferredWidth() ...{
int width = 0;
ListCellRenderer renderer = list.getCellRenderer();

for (int index = 0, count = list.getModel().getSize(); index < count; index++) ...{
Object element = list.getModel().getElementAt(index);
Component comp = renderer.getListCellRendererComponent(list, element, index, false,
false);
Dimension dim = comp.getPreferredSize();
if (dim.width > width)
width = dim.width;
}
return width;
}

void syncListSelectionWithComboBoxSelection() ...{
int selectedIndex = comboBox.getSelectedIndex();

if (selectedIndex == -1) ...{
list.clearSelection();

} else ...{
list.setSelectedIndex(selectedIndex);
}
}

public void setPopupWidth(int width) ...{
this.width = width;
}
}
其实重写UI的原因就是因为需要重写这个Popup. Java原先的Popup是不显示横向ScrollBar的. 而且更改了ScrollBar的显示原则以后, 那么尺寸也必须重新计算了.