这个不知道有没有人写过.
有点限制, 因为替换了UI, 所以只能在Metal下看才不会有异样的感觉.
import
java.awt.Dimension;
import
java.util.Vector;
import
javax.swing.ComboBoxModel;
import
javax.swing.JComboBox;
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/** */
/**
* Created at 2006-7-25 13:06:10<br>
* 下拉延长的下拉框
*/
@SuppressWarnings(
"
serial
"
)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
ExtendedComboBox
extends
JComboBox
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public ExtendedComboBox() ...{
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* @param aModel
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public ExtendedComboBox(ComboBoxModel aModel) ...{
super(aModel);
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* @param items
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public ExtendedComboBox(Object[] items) ...{
super(items);
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* @param items
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public ExtendedComboBox(Vector<?> items) ...{
super(items);
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* (非 Javadoc)
*
* @see javax.swing.JComboBox#updateUI()
*/
@Override
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void updateUI() ...{
setUI(new ExtendedComboBoxUI());
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* (非 Javadoc)<br>
* 如果需要修改最适合尺寸, 重写此方法
*
* @see javax.swing.JComponent#getPreferredSize()
*/
@Override
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
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;
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/** */
/**
* Created at 2006-7-25 13:09:13<br>
* 延长的ComboBoxUI
*/
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
ExtendedComboBoxUI
extends
MetalComboBoxUI
...
{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public static ComponentUI createUI(JComponent c) ...{
return new ExtendedComboBoxUI();
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* (非 Javadoc)
*
* @see javax.swing.plaf.basic.BasicComboBoxUI#createPopup()
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
protected ComboPopup createPopup() ...{
ExtendedComboPopup popup = new ExtendedComboPopup(comboBox);
popup.getAccessibleContext().setAccessibleParent(comboBox);
return popup;
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
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;
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
/** */
/**
* Created at 2006-7-25 13:07:04<br>
* 延长的下拉框弹出菜单
*/
@SuppressWarnings(
"
serial
"
)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
class
ExtendedComboPopup
extends
BasicComboPopup
...
{
private int width = -1;
private int maxWidth = 300;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* @param combo
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public ExtendedComboPopup(JComboBox combo) ...{
super(combo);
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* (非 Javadoc)
*
* @see javax.swing.plaf.basic.BasicComboPopup#createScroller()
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
protected JScrollPane createScroller() ...{
return new JScrollPane(list, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* (非 Javadoc)
*
* @see java.awt.Component#show()
*/
@SuppressWarnings("deprecation")
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
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();
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
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);
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
/** *//**
* 计算当前的最适合宽度
*
* @return
*/
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
private int calcPreferredWidth() ...{
int width = 0;
ListCellRenderer renderer = list.getCellRenderer();
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
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;
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
void syncListSelectionWithComboBoxSelection() ...{
int selectedIndex = comboBox.getSelectedIndex();
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if (selectedIndex == -1) ...{
list.clearSelection();
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
} else ...{
list.setSelectedIndex(selectedIndex);
}
}
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void setPopupWidth(int width) ...{
this.width = width;
}
}
其实重写UI的原因就是因为需要重写这个Popup. Java原先的Popup是不显示横向ScrollBar的. 而且更改了ScrollBar的显示原则以后, 那么尺寸也必须重新计算了.