JComboBox のポップアップの幅を変更する方法を探しています。基本的に、ポップアップは、コンボボックスの現在の幅ではなく、最も幅の広いコンボボックス エントリが必要とする幅にする必要があります。
これを達成する方法を私が知っている唯一の方法は、ComboBoxUI のカスタム インスタンスを作成し、それを JComboBox に設定することです (サンプル コードは目標を示しています: Top Combobox はワイド ポップアップを表示し、Bottom はデフォルトの動作です)。ただし、これは ComboBox の UI を置き換えるため、一部の L&F では奇妙に見える場合があります (たとえば、WinXP Luna テーマでは、ComboBox は Classic テーマのように見えます)。
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);
}
}