为什么JComboBox会忽略PrototypeDisplayValue

与这两个post@iMohammad相关联, 使用JButton增加/减少textArea中的字体大小和单击JButton Java时更改字体样式 …,我面临着来自JComboBox的非常有趣的问题,方法是将setPrototypeDisplayValue作为参数传递对于JComboBox's size在屏幕上JComboBox's size

请问如何动态调整JComboBox大小取决于Font ,同样适用于我在sscce中尝试过的另一个JComponents

 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ComboBoxFontChange extends JFrame { private static final long serialVersionUID = 1L; private JComboBox cbox = new JComboBox(); private JTextField tfield = new JTextField("Change"); private JLabel label = new JLabel("Cash"); private JButton button = new JButton("++ Font"); private JTextField text; private JPanel panel = new JPanel(); public ComboBoxFontChange() { super("Combo Box Font change"); text = (JTextField) cbox.getEditor().getEditorComponent(); cbox.addItem("Change"); cbox.addItem("Cash"); cbox.addItem("Font"); tfield.setColumns(5); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Font font = cbox.getFont(); font = font.deriveFont((float) (font.getSize2D() * 1.10)); cbox.setFont(font); // EDIT cbox.setPrototypeDisplayValue(cbox.getSelectedItem().toString()); tfield.setFont(font); button.setFont(font); label.setFont(font); //panel.revalidate(); //panel.repaint(); pack(); } }); //panel.setLayout(new GridLayout(2, 2, 10, 10)); panel.add(cbox); panel.add(label); panel.add(tfield); panel.add(button); setDefaultCloseOperation(EXIT_ON_CLOSE); add(panel); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { ComboBoxFontChange frame = new ComboBoxFontChange(); frame.pack(); frame.setVisible(true); } }); } } 

我调试了你的SSCCE,传递给setPrototypeDisplayValue的值是空字符串。 将行更改为

 cbox.setPrototypeDisplayValue(cbox.getSelectedItem()); 

使一切按预期工作。 删除对setPrototypDisplayValue的调用也会使程序按预期运行。

编辑:

另一个问题是没有为原型显示值触发事件,因为您将其设置为之前的值,并且仅在值实际更改时才触发事件。 添加cbox.setPrototypeDisplayValue("");cbox.setPrototypeDisplayValue(cbox.getSelectedItem().toString()) ,所有内容都按预期运行,即使在JDK 1.6上也是如此。 我同意,鉴于字体已更改,应重新计算首选大小,但至少此更改是一种解决方法。

我试过JB Nizet所说的。 但对我来说,comboBox的大小并没有改变。 你呢?

所以我尝试了以下,随着我增加字体大小,combobox尺寸增加了。

 cbox.setFont(font); cbox.updateUI(); 

我也删除了该行

 cbox.setPrototypeDisplayValue(text.getText()); 

作为参考, GridLayout和8次点击在Mac OS X上给出了这个结果:

 panel.setLayout(new GridLayout(0, 1, 10, 10)); 

组合: 二合一 弹出: 弹出

cbox.updateUI()cbox.updateUI()恢复了Aqua UI委托com.apple.laf.AquaComboBoxUI规定的默认值。

以下是BasicComboBoxUI中的代码:

  else if ( propertyName == "font" ) { listBox.setFont( comboBox.getFont() ); if ( editor != null ) { editor.setFont( comboBox.getFont() ); } isMinimumSizeDirty = true; comboBox.validate(); } else if ( propertyName == JComponent.TOOL_TIP_TEXT_KEY ) { updateToolTipTextForChildren(); } else if ( propertyName == BasicComboBoxUI.IS_TABLE_CELL_EDITOR ) { Boolean inTable = (Boolean)e.getNewValue(); isTableCellEditor = inTable.equals(Boolean.TRUE) ? true : false; } else if (propertyName == "prototypeDisplayValue") { isMinimumSizeDirty = true; isDisplaySizeDirty = true; comboBox.revalidate(); } 

由于某种原因,字体更改仅重置“最小大小”而不是“显示大小”。