我正在寻找一种改变 JComboBox 弹出窗口宽度的方法。基本上,弹出窗口应该与组合框条目所需的最宽一样宽,而不是组合框当前的宽度。
我知道如何实现此目的的唯一方法是创建 ComboBoxUI 的自定义实例并将其设置在 JComboBox 上(示例代码演示了目标:Top Combobox 显示宽弹出窗口,Bottom 是默认行为)。然而,由于这取代了 ComboBox 的 UI,它在某些 L&F 上可能看起来很奇怪(例如,对于 WinXP Luna 主题,ComboBox 看起来像经典主题)。
有没有办法以 L&F 不可知论的方式实现这种行为?
public class CustomCombo extends JComboBox {
final static class CustomComboUI 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;
}
}
{
setUI(new CustomComboUI());
}
public static void main(String[] argv) {
try {
final String className = UIManager.getSystemLookAndFeelClassName();
UIManager.setLookAndFeel(className);
} catch (final Exception e) {
// ignore
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createGUI();
}
});
}
public static void createGUI() {
JComboBox combo1 = new CustomCombo();
JComboBox combo2 = new JComboBox();
JPanel panel = new JPanel();
JFrame frame = new JFrame("Testframe");
combo1.addItem("1 Short item");
combo1.addItem("2 A very long Item name that should display completely in the popup");
combo1.addItem("3 Another short one");
combo2.addItem("1 Short item");
combo2.addItem("2 A very long Item name that should display completely in the popup");
combo2.addItem("3 Another short one");
panel.setPreferredSize(new Dimension(30, 50));
panel.setLayout(new GridBagLayout());
GridBagConstraints gc;
gc = new GridBagConstraints(0, 0, 1, 1, 1D, 0D, GridBagConstraints.WEST,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0);
panel.add(combo1, gc);
gc = new GridBagConstraints(0, 1, 1, 1, 1D, 0D, GridBagConstraints.WEST,
GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0);
panel.add(combo2, gc);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(panel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
}
最佳答案
通过使用 GBC,您可以在容器中设置适当的高度和重量
@trashgod 提到的下一种方法是使用
JComboBox.setPrototypeDisplayValue()
设置 使用 Combo Box Popup通过@camickr
派生
<JPopup
必须使用pack()
否则太难改变它的Dimension
easill
PreferredSize
.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
public class ComboBoxExample extends JPanel implements ActionListener {
//http://stackoverflow.com/a/5058210/714968
private static final long serialVersionUID = 1L;
private JComboBox comboBox;
public ComboBoxExample() {
String[] petStrings = {"Select Pet", "Bird", "Cat", "Dog", "Rabbit", "Pig", "Other"};
comboBox = new JComboBox(petStrings);
comboBox.setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
add(comboBox, BorderLayout.PAGE_START);
JFrame frame = new JFrame("ComboBoxExample");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(comboBox);
frame.setName("ComboBoxExample");
frame.setLocation(150, 150);
frame.pack();
frame.setVisible(true);
Timer timer = new javax.swing.Timer(2000, this);
timer.start();
}
public void actionPerformed(ActionEvent e) {
comboBox.showPopup();
Object child = comboBox.getAccessibleContext().getAccessibleChild(0);
BasicComboPopup popup = (BasicComboPopup) child;
popup.setName("BasicComboPopup");
JList list = popup.getList();
Container c = SwingUtilities.getAncestorOfClass(JScrollPane.class, list);
JScrollPane scrollPane = (JScrollPane) c;
Dimension size = scrollPane.getSize();
if (size.width > 30) {
size.width -= 5;
}
scrollPane.setPreferredSize(size);
scrollPane.setMaximumSize(size);
Dimension popupSize = popup.getSize();
popupSize.width = size.width;
Component parent = popup.getParent();
parent.setSize(popupSize);
parent.validate();
parent.repaint();
Window mainFrame = SwingUtilities.windowForComponent(comboBox);
//Returns the first Window ancestor of c, or null if c is not contained inside a Window.
System.out.println(mainFrame.getName());
Window popupWindow = SwingUtilities.windowForComponent(popup);
System.out.println(popupWindow.getName());
Window popupWindowa = SwingUtilities.windowForComponent(c);
System.out.println(popupWindowa.getName());
Window mainFrame1 = SwingUtilities.getWindowAncestor(comboBox);
//Returns the first Window ancestor of c, or null if c is not contained inside a Window.
System.out.println(mainFrame1.getName());
Window popupWindow1 = SwingUtilities.getWindowAncestor(popup);
System.out.println(popupWindow1.getName());
Component mainFrame2 = SwingUtilities.getRoot(comboBox);
//Returns the root component for the current component tree.
System.out.println(mainFrame2.getName());
Component popupWindow2 = SwingUtilities.getRoot(popup);
System.out.println(popupWindow2.getName());
// For heavy weight popups you need always to pack() for the window
if (popupWindow != mainFrame) {
popupWindow.pack();
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
ComboBoxExample comboBoxExample = new ComboBoxExample();
}
});
}
}
关于java - 在不影响外观的情况下更改 JComboBox 弹出窗口大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11435138/