java - 如何更改 JComboBox 显示区域的外观

标签 java swing jcombobox listcellrenderer

我正在为 JComboBox 使用自定义 BasicComboBoxRenderer,并且更改了下拉列表中项目的外观。但是,这些更改也适用于组合框中显示的单个顶部项目(不知道如何调用它)。

如果可能的话,我希望顶部项目独立于列表中的其他项目。我还想在聚焦时去掉顶部项目的蓝色(setFocusable(false) 不是我想要的)。

我尝试使用“渲染器索引”(-1) 来影响顶部项目,但似乎没有帮助。

有什么想法吗?

P.S 不幸的是,我无法添加更清晰的图像(没有声誉)。

编辑:当我说我希望顶部项目独立于下拉列表中的所有其他项目时,我的意思是始终看起来与其他项目不同。例如,在我的自定义 BasicComboBoxRenderer 中,我将所选项目设置为具有不同的背景,但此背景也适用于顶部项目(因为所选项目成为组合框的顶部项目)。

编辑2:顶部项目=我的意思是组合框显示区域,所以我想影响显示区域中显示的项目,而不是下拉列表中的第一个项目。我设法通过在组合框本身上使用 setBackground 和 setFocusable(false) 来做到这一点(这不是很有帮助,因为我想保留焦点机制)。但问题是(焦点问题除外),例如,如果我通过自定义 BasicComboBoxRenderer 或 ListCellRenderer 类在列表中的每个项目上设置边框,则相同的边框会出现在显示区域中显示的项目上。所以这里有两个问题:

--有什么方法可以区分下拉列表中的项目和显示区域中的单个项目的布局吗?

--有没有办法在不禁用焦点机制的情况下禁用组合框的焦点颜色,就像我们在按钮上使用 setFocusPainted(false) 一样? (我还尝试在组合框中添加自定义 FocusListener,但通过 focusGained() 对背景所做的任何更改仅影响按钮,而不影响显示区域中显示的项目)。

抱歉造成困惑和多次编辑......

最佳答案

  • 看看Combo Box Prompt作者:@camickr,

  • 定义的提示无法从 JComboBox.getSelectedXxx 返回任何值

编辑

BasicComboBoxRenderer 或 ListCellRenderer 可以这样做

import java.awt.*;
import javax.swing.*;

public class TestHighLightRow {

    public void makeUI() {
        Object[] data = {"One", "Two", "Three"};
        JComboBox comboBox = new JComboBox(data);
        comboBox.setPreferredSize(comboBox.getPreferredSize());
        comboBox.setRenderer(new HighLightRowRenderer(comboBox.getRenderer()));
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(comboBox);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestHighLightRow().makeUI();
            }
        });
    }

    public class HighLightRowRenderer implements ListCellRenderer {

        private final ListCellRenderer delegate;
        private int height = -1;

        public HighLightRowRenderer(ListCellRenderer delegate) {
            this.delegate = delegate;
        }

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            Component component = delegate.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            Dimension size = component.getPreferredSize();
            if (index == 0) {
                component.setBackground(Color.red);
                if (component instanceof JLabel) {
                    ((JLabel) component).setHorizontalTextPosition(JLabel.CENTER);
                }
            }
            return component;
        }
    }
}

编辑2

JComboBox 有两种状态

  • 可编辑

  • 不可编辑

基本上所有值都可以从 UIManager、快捷方式访问

import java.awt.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.metal.MetalComboBoxButton;

public class MyComboBox {

    private Vector<String> listSomeString = new Vector<String>();
    private JComboBox someComboBox = new JComboBox(listSomeString);
    private JComboBox editableComboBox = new JComboBox(listSomeString);
    private JComboBox non_EditableComboBox = new JComboBox(listSomeString);
    private JFrame frame;

    public MyComboBox() {
        listSomeString.add("-");
        listSomeString.add("Snowboarding");
        listSomeString.add("Rowing");
        listSomeString.add("Knitting");
        listSomeString.add("Speed reading");
//
        someComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
        someComboBox.setFont(new Font("Serif", Font.BOLD, 16));
        someComboBox.setEditable(true);
        someComboBox.getEditor().getEditorComponent().setBackground(Color.YELLOW);
        ((JTextField) someComboBox.getEditor().getEditorComponent()).setBackground(Color.YELLOW);
//
        editableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
        editableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
        editableComboBox.setEditable(true);
        JTextField text = ((JTextField) editableComboBox.getEditor().getEditorComponent());
        text.setBackground(Color.YELLOW);
        JComboBox coloredArrowsCombo = editableComboBox;
        Component[] comp = coloredArrowsCombo.getComponents();
        for (int i = 0; i < comp.length; i++) {
            if (comp[i] instanceof MetalComboBoxButton) {
                MetalComboBoxButton coloredArrowsButton = (MetalComboBoxButton) comp[i];
                coloredArrowsButton.setBackground(null);
                break;
            }
        }
//
        non_EditableComboBox.setPrototypeDisplayValue("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
        non_EditableComboBox.setFont(new Font("Serif", Font.BOLD, 16));
//
        frame = new JFrame();
        frame.setLayout(new GridLayout(0, 1, 10, 10));
        frame.add(someComboBox);
        frame.add(editableComboBox);
        frame.add(non_EditableComboBox);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(100, 100);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        UIManager.put("ComboBox.background", new ColorUIResource(Color.yellow));
        UIManager.put("JTextField.background", new ColorUIResource(Color.yellow));
        UIManager.put("ComboBox.selectionBackground", new ColorUIResource(Color.magenta));
        UIManager.put("ComboBox.selectionForeground", new ColorUIResource(Color.blue));
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                MyComboBox aCTF = new MyComboBox();
            }
        });
    }
}

关于java - 如何更改 JComboBox 显示区域的外观,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11420217/

相关文章:

java - 使用 Java 从网站获取内容

java - "AL lib: alc_cleanup: 1 device not closed"是什么意思?

java - 添加到 JPanel 时 JScrollPane 未调整大小

java - 如何从 JTextField 获取值到 JComboBox?

java - 当与 JTable 内的 JComboBox 交互时,如何保持 JComboBox 的焦点?

java - 用颜色填充复杂图像

java - 调用了 Spring MVC Controller 但获得 404 渲染 View

Java spring JPA Repository Entity 未被删除

java - 检测 jpanel 焦点的变化

java - JComboBox 获取项目