JComboBox 首选大小,选择了空值但不在 ComboBoxModel 中

Gui*_*let 5 java layout swing jcombobox

我有以下情况:在 JCombobox 中,首选大小基于最大项目大小。但是,此计算没有考虑为 呈现的值null。它只关心模型内部的值。因此,当用于呈现 null 值的文本大于其他元素时,标签将被截断,并且末尾有三个点 (...)。我想避免这种情况。

这是我正在谈论的内容的一个小演示:

呈现截断的空值

import java.awt.Component;
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;

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" });
        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) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestComboBox().initUI();
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我想知道你有什么建议吗?到目前为止,我的想法是扩展 JComboBox,覆盖首选大小,还执行空值的渲染,并获取对 super.preferredSize 的调用的最大尺寸和空值渲染的尺寸之一。但我觉得这有点令人失望。

我真的不想使用prototypeDisplayValue绝对不是一个选项,因为我不知道该下拉列表中的值

Rob*_*bin 2

我没有在代码中对此进行测试,但我的方法是:

  1. 确定渲染器返回的 和实际preferredSize的之间的差异。不是通过使用任何硬编码值,而是通过创建一个仅包含一个项目和一个已知渲染器的后台,并将首选大小与已知渲染器返回的大小进行比较。ComponentpreferredSizeJComboBoxJComboBoxJComboBoxComponent
  2. 每次通过将侦听器附加到外观来更改外观时,请重复步骤 1UIManager
  3. 覆盖getPreferredSize实际的并返回宽度JComboBox的最大值super.getPreferredSize()getPreferredSize( rendererComponent ) + calculatedDifference

这应该可以解决外观问题,避免不必要的计算,并且您可以轻松创建JComboBox包含此功能的扩展。