所以這是我這麼遠,但一個主要問題是跨大號&˚F問題。另一種方法是遍歷ComboBox模型的所有值和「無選擇」值,並檢查哪一個是最長的。然後我可以將它設置爲prototypeDisplayValue。問題是我需要一個圖形上下文來衡量每個字符串的邊界。
以下是我們用@Enwired和@Robin發現的兩種解決方案。感謝他們兩人。
編輯:在與@羅賓討論後,我發現這個解決方案實際上更簡單,適用於所有平臺和外觀。唯一的缺點是我們需要創建一個額外的JComboBox。
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UnsupportedLookAndFeelException;
public class TestComboBox {
protected void initUI() {
JFrame frame = new JFrame(TestComboBox.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridBagLayout());
JComboBox comboBox = new JComboBox(new Object[] { "Something", "Stuff", "Beep" }) {
private JComboBox internal;
private JComboBox getInternalComboBox() {
if (internal == null) {
internal = new JComboBox(new Object[] { null });
}
return internal;
}
@Override
public Dimension getPreferredSize() {
Dimension preferredSize = super.getPreferredSize();
if (getSelectedItem() == null) {
getInternalComboBox().setRenderer(getRenderer());
Dimension nullDimension = getInternalComboBox().getPreferredSize();
preferredSize.width = Math.max(preferredSize.width, nullDimension.width);
preferredSize.height = Math.max(preferredSize.height, nullDimension.height);
}
return preferredSize;
}
@Override
public void updateUI() {
internal = null;
super.updateUI();
}
};
comboBox.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value == null) {
setText("No selection");
}
return comp;
}
});
comboBox.setSelectedItem(null);
panel.add(comboBox);
frame.add(panel);
frame.setSize(200, 100);
frame.setVisible(true);
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestComboBox().initUI();
}
});
}
}
編輯2:與@Enwired討論在此之後的替代解決方案提出了這是直接重寫ListCellRenderer的getPreferredSize。在這其中,你可以嘗試去通過不同得的L- & F.
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
import javax.swing.UnsupportedLookAndFeelException;
public class TestComboBox {
protected void initUI() {
final JFrame frame = new JFrame(TestComboBox.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridBagLayout());
JComboBox comboBox = new JComboBox(new Object[] { "Something", "Stuff", "Beep" });
comboBox.setRenderer(new DefaultListCellRenderer() {
private Dimension nullDimesion;
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
if (value != null && nullDimesion == null) {
nullDimesion = ((JComponent) getListCellRendererComponent(list, null, -1, false, false)).getPreferredSize();
}
Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value == null) {
setText("No selection");
}
return comp;
}
@Override
public Dimension getPreferredSize() {
Dimension preferredSize = super.getPreferredSize();
if (nullDimesion != null) {
preferredSize.width = Math.max(preferredSize.width, nullDimesion.width);
preferredSize.height = Math.max(preferredSize.height, nullDimesion.height);
}
return preferredSize;
}
@Override
public void updateUI() {
nullDimesion = null;
super.updateUI();
}
});
comboBox.setSelectedItem(null);
final JComboBox uiComboBox = new JComboBox(UIManager.getInstalledLookAndFeels());
uiComboBox.setRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof LookAndFeelInfo) {
LookAndFeelInfo info = (LookAndFeelInfo) value;
setText(info.getName());
}
return comp;
}
});
uiComboBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(((LookAndFeelInfo) uiComboBox.getSelectedItem()).getClassName());
SwingUtilities.updateComponentTreeUI(frame);
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (InstantiationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IllegalAccessException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (UnsupportedLookAndFeelException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
}
});
panel.add(comboBox);
panel.add(uiComboBox);
frame.add(panel);
frame.setSize(300, 100);
frame.setVisible(true);
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestComboBox().initUI();
}
});
}
}
JComboBox.setPrototypeDisplayValue()在需要強制屏幕大小的情況下,爲我檢查Rob的代碼示例 – mKorbel 2012-07-20 15:37:31
@mKorbel,設置原型顯示值與強制首選大小相同,我希望以避免這種情況。我不知道組合框內的值,在某些情況下,它可能會比空值渲染大。我也不希望組合框通過強制首選大小來佔用過多的空間。我只是希望我的JComboBox採用確切的所需空間來顯示所有值,包括null值,儘管null值不在ComboBoxModel中。 – 2012-07-20 15:40:59
'我不知道組合框內的值,這可能會在已經可見的GUI – mKorbel 2012-07-20 17:39:16