Java 如何更改JComboBox下拉列表的宽度?
我有一个可编辑的Java 如何更改JComboBox下拉列表的宽度?,java,swing,combobox,Java,Swing,Combobox,我有一个可编辑的JComboBox,其中包含一个单字母值列表。因此,组合框非常小 每一个字母都有一个特殊的含义,如果是很少使用的字母,用户有时不清楚。因此,我创建了一个自定义的ListCellRenderer,显示下拉列表中每个字母的含义 不幸的是,这个解释不适合下拉列表,因为它太小了,因为它与组合框的宽度相同 有没有办法使下拉列表比组合框更宽 这就是我想要实现的目标: --------------------- | Small JCombobox | V | ---------------
JComboBox
,其中包含一个单字母值列表。因此,组合框非常小
每一个字母都有一个特殊的含义,如果是很少使用的字母,用户有时不清楚。因此,我创建了一个自定义的ListCellRenderer
,显示下拉列表中每个字母的含义
不幸的是,这个解释不适合下拉列表,因为它太小了,因为它与组合框的宽度相同
有没有办法使下拉列表比组合框更宽
这就是我想要实现的目标:
---------------------
| Small JCombobox | V |
--------------------------------------------
| "Long item 1" |
--------------------------------------------
| "Long item 2" |
--------------------------------------------
| "Long item 3" |
--------------------------------------------
我无法更改组合框的宽度,因为该应用程序是旧的遗留应用程序的翻版,其中某些内容必须与以前完全相同。(在这种情况下,组合框必须不惜一切代价保持小尺寸)听起来您需要自己编写 有一个很好的例子说明了如何实现这一点
另外请注意,您可能感兴趣的方法是
createPopup()
方法。这是为组合框创建弹出窗口的方法,您可以在其中对其进行自定义。我认为使用公共API实现这一点的唯一方法是编写自定义UI(目前正在处理此问题)
如果您只是想要一些快速而肮脏的东西,我发现这样做可以使用实现细节():
把这个放在一个盒子里,它可能对你有用
或者,您可以使用以下代码:
这是Santhosh Kumar提出的一个很好的解决方案,不需要搞乱UI和其他类似的讨厌的东西
这里有一个很好的解决方案 在设置弹出列表的维度之前,它从中获取最大的项目,并计算完整显示该项目所需的宽度
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);
}
}
希望对以后的参考有用 您可能需要使用
setSize()
方法
combo.setSize(200, combo.getPreferredSize().height);
这里有一段简单的代码,没有扩展JComboBox或其他任何类 在本例中,with下拉列表始终为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);
}
};
}
});
这两种方法似乎都有效,但popupMenuWillBecomeVisible仅在您还提供自定义ListCellRenderer的情况下才有效。默认的一个似乎是按原始大小剪切字符串。当JComboBox(OSX)中有以下8项时,第一个不适用于我。第二个解决方案甚至在MAC上也有windows的外观……第一个解决方案不起作用,因为在设置大小之前会调用popupMenuWillBecomeVisible(请参见BasicComboPopup中的show()),所以您在该侦听器中设置的任何大小都将被覆盖。答案可以在JDK源代码“BasicComboPopup#getPopupLocation”中找到,我们可以将其计算大小和调整大小的解决方案复制到PopupMenuListener的“popupMenuWillBecomeVisible()”,对于过长的项目,我们甚至可以设置弹出菜单的位置(其位置为“屏幕位置”)。此解决方案不调整高度,只调整宽度。调整高度要复杂得多。此解决方案打破了原始组合框的“箭头”。应用后,不再有箭头注意:链接已断开
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);
}
}
return widest + 5;
combo.setSize(200, combo.getPreferredSize().height);
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);
}
};
}
});