我有一个可编辑的JComboBox
,其中包含单个字母值的列表。因此,组合框非常小。
每个字母都有特殊含义,对于很少使用的字母,有时用户不清楚。因此,我创建了一个自定义ListCellRenderer
,它显示了下拉列表中每个字母的含义。
不幸的是,这个解释不适合下拉列表,因为它与小的一样,因为它与组合框的宽度相同。
有没有办法让下拉列表比组合框更宽?
这就是我想要实现的目标:
---------------------
| Small JCombobox | V |
--------------------------------------------
| "Long item 1" |
--------------------------------------------
| "Long item 2" |
--------------------------------------------
| "Long item 3" |
--------------------------------------------
我无法改变组合框的宽度,因为该应用程序是旧的遗留应用程序的重新创建,其中某些东西必须与之前完全一样。 (在这种情况下,组合框必须不惜一切代价保持它的小尺寸)
答案 0 :(得分:16)
答案 1 :(得分:14)
我认为使用公共API执行此操作的唯一方法是编写自定义UI(two bugs处理此问题。)
如果你只是想要快速和肮脏的东西,我发现这种方式使用实现细节来做(here):
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
JComboBox box = (JComboBox) e.getSource();
Object comp = box.getUI().getAccessibleChild(box, 0);
if (!(comp instanceof JPopupMenu)) return;
JComponent scrollPane = (JComponent) ((JPopupMenu) comp).getComponent(0);
Dimension size = new Dimension();
size.width = box.getPreferredSize().width;
size.height = scrollPane.getPreferredSize().height;
scrollPane.setPreferredSize(size);
// following line for Tiger
// scrollPane.setMaximumSize(size);
}
将其放在PopupMenuListener
中,可能适合您。
或者您可以使用first linked bug:
中的代码class StyledComboBoxUI extends BasicComboBoxUI {
protected ComboPopup createPopup() {
BasicComboPopup popup = new BasicComboPopup(comboBox) {
@Override
protected Rectangle computePopupBounds(int px,int py,int pw,int ph) {
return super.computePopupBounds(
px,py,Math.max(comboBox.getPreferredSize().width,pw),ph
);
}
};
popup.getAccessibleContext().setAccessibleParent(comboBox);
return popup;
}
}
class StyledComboBox extends JComboBox {
public StyledComboBox() {
setUI(new StyledComboBoxUI());
}
}
答案 2 :(得分:14)
这是Santhosh Kumar的一个很好的解决方案,不需要弄乱UI和其他令人讨厌的东西!
http://www.jroller.com/santhosh/entry/make_jcombobox_popup_wide_enough
import javax.swing.*;
import java.awt.*;
import java.util.Vector;
// got this workaround from the following bug:
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4618607
public class WideComboBox extends JComboBox{
public WideComboBox() {
}
public WideComboBox(final Object items[]){
super(items);
}
public WideComboBox(Vector items) {
super(items);
}
public WideComboBox(ComboBoxModel aModel) {
super(aModel);
}
private boolean layingOut = false;
public void doLayout(){
try{
layingOut = true;
super.doLayout();
}finally{
layingOut = false;
}
}
public Dimension getSize(){
Dimension dim = super.getSize();
if(!layingOut)
dim.width = Math.max(dim.width, getPreferredSize().width);
return dim;
}
}
答案 3 :(得分:5)
这是tutiez的一个很好的解决方案。
在设置弹出列表的维度之前,它会从中获取最大的项目并计算完全显示它所需的宽度。
public class WiderDropDownCombo extends JComboBox {
private String type;
private boolean layingOut = false;
private int widestLengh = 0;
private boolean wide = false;
public WiderDropDownCombo(Object[] objs) {
super(objs);
}
public boolean isWide() {
return wide;
}
// Setting the JComboBox wide
public void setWide(boolean wide) {
this.wide = wide;
widestLengh = getWidestItemWidth();
}
public Dimension getSize() {
Dimension dim = super.getSize();
if (!layingOut && isWide())
dim.width = Math.max(widestLengh, dim.width);
return dim;
}
public int getWidestItemWidth() {
int numOfItems = this.getItemCount();
Font font = this.getFont();
FontMetrics metrics = this.getFontMetrics(font);
int widest = 0;
for (int i = 0; i < numOfItems; i++) {
Object item = this.getItemAt(i);
int lineWidth = metrics.stringWidth(item.toString());
widest = Math.max(widest, lineWidth);
}
return widest + 5;
}
public void doLayout() {
try {
layingOut = true;
super.doLayout();
} finally {
layingOut = false;
}
}
public String getType() {
return type;
}
public void setType(String t) {
type = t;
}
public static void main(String[] args) {
String title = "Combo Test";
JFrame frame = new JFrame(title);
String[] items = {
"I need lot of width to be visible , oh am I visible now",
"I need lot of width to be visible , oh am I visible now" };
WiderDropDownCombo simpleCombo = new WiderDropDownCombo(items);
simpleCombo.setPreferredSize(new Dimension(180, 20));
simpleCombo.setWide(true);
JLabel label = new JLabel("Wider Drop Down Demo");
frame.getContentPane().add(simpleCombo, BorderLayout.NORTH);
frame.getContentPane().add(label, BorderLayout.SOUTH);
int width = 200;
int height = 150;
frame.setSize(width, height);
frame.setVisible(true);
}
}
上面的代码已经成为快速测试的主要内容。但请注意,如果您想要进行垂直滚动,可以将下面的语句调整为 20 。
return widest + 5;
希望它对将来参考有用!
答案 4 :(得分:1)
听起来你需要自己编写ComboBoxUI。
有一个很好的例子here,展示了如何实现这一目标。
另请注意,您可能感兴趣的方法是createPopup()
方法。这是为组合框创建弹出窗口的方法,您可以在其中自定义它。
答案 5 :(得分:0)
您可能希望使用setSize()
方法。
combo.setSize(200, combo.getPreferredSize().height);
答案 6 :(得分:0)
这里有一段简单的代码,没有扩展JComboBox,也没有任何类
在此示例中,下拉列表始终为500。 您也可以修改高度或位置。
FaceCorrectiveReasonComboBox.getTextComponent().setUI(new BasicComboBoxUI() {
@Override protected ComboPopup createPopup() {
return new BasicComboPopup(comboBox) {
protected Rectangle computePopupBounds(int px,int py,int pw,int ph) {
return super.computePopupBounds(px, py, 500, ph);
}
};
}
});