下拉控件的颜色和不可编辑的JComboBox中的边框

时间:2010-12-29 20:21:26

标签: java swing jcombobox

不可编辑的JComboBox中所选项目的背景颜色是一种蓝色:

alt text

我知道您可以将其更改为其他颜色,例如白色,例如使用following code

jComboBox1.setRenderer(new DefaultListCellRenderer() {
    @Override
    public void paint(Graphics g) {
        setBackground(Color.WHITE);
        setForeground(Color.BLACK);
        super.paint(g);
    }
});

这给你这样的东西:

alt text

但是,如果双击该组合框,其中一些变为灰色(带有三角形和边框的部分):

alt text

双击时,有没有办法阻止这些部件变灰?

请注意,如果你先调用super.paint(),整个事情会变暗(包括“Select ...”后面的部分),所以这没有帮助。

4 个答案:

答案 0 :(得分:1)

一些事情:

  1. 组合框的外观(显示区域,箭头,下拉)取决于LAF。你的屏幕截图建议使用WinXP。如果你必须支持任何其他LAF,一定要测试它,因为对一个LAF起作用的可能不适用于另一个。我发现对于JComboBoxes来说尤其如此。

  2. 像Twister建议的那样,通过覆盖paint()方法来改变颜色可能不是最好的方法。只需设置组合框本身的背景/前景色即可。如果您想更改下拉列表本身的颜色(我不清楚您是否要这样做),然后添加一个自定义渲染器来覆盖getListCellRendererComponent以设置背景/前景。 / p>

    public static class CustomRenderer extends DefaultListCellRenderer {
    
    @Override
    public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {
        super.getListCellRendererComponent(list, value, index, isSelected,
                cellHasFocus);
        setBackground(Color.WHITE);
        setForeground(Color.BLACK);     
        return this;
    }       
    

    }

  3. 灰色三角形和边框的外观是因为组合框现在具有焦点。你可以让它不可聚焦,着色就会消失。但是,这可能不是您想要的行为。

    JComboBox combo = new JComboBox(new Object[]{"Dog", "Cat", "Bird"});
    combo.setBackground(Color.WHITE);
    combo.setForeground(Color.BLACK);
    combo.setFocusable(false);
    

答案 1 :(得分:1)

不确定OP到底想实现什么,但这是我的JComboBox着色配方:

static public void main(String[] args) {
    JFrame window = new JFrame("Coloring ComboBox");
    window.setSize(170, 150);
    window.setLocationRelativeTo(null);
    window.setLayout(null);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //---textArea is just for focus switching
    JTextArea textArea = new JTextArea();
    textArea.setBounds(5, 5, 140, 25);
    window.add(textArea);

    UIManager.put("ComboBox.selectionBackground", Color.magenta); //---focused background color
    //---see comboBox's UIDefaults for more tweaks

    JComboBox<String> coloredCombo = new JComboBox<String>(new String[]{"Dog", "Cat", "Bird"});
    coloredCombo.setEditable(false);
    coloredCombo.setUI(new BasicComboBoxUI() {
            @SuppressWarnings({"serial"})
            @Override
            protected ComboPopup createPopup() {
                return new BasicComboPopup(coloredCombo) {
                    {
                        //---style popup anyway you like
                        this.setBorder(BorderFactory.createLineBorder(Color.green, 2));//---popup's border color
                    }
                };
            }
            @Override
            protected JButton createArrowButton() {
                //---style arrow button anyway you like
                JButton result = new JButton();
                result.setBackground(Color.orange);//---button's color
                return result;
            }
        });

    coloredCombo.setBorder(BorderFactory.createLineBorder(Color.red, 2));//---border color
    coloredCombo.setBackground(Color.yellow); //---not focused background color

    coloredCombo.setRenderer(new ListCellRenderer<String>() {
        @Override
        public Component getListCellRendererComponent(JList<? extends String> list, String value, int index,
                boolean isSelected, boolean cellHasFocus) {
            JLabel result = new JLabel(value);
            result.setOpaque(true);
            result.setBackground(isSelected ? Color.cyan : Color.blue); //---item background color
            return result;
        }
    });
    coloredCombo.setBounds(5, 35, 140, 25);
    window.add(coloredCombo);

    window.setVisible(true);
}

当然,这只是一个示例,我建议您创建一个精美的自定义类以供重用。enter image description here

答案 2 :(得分:0)

首先,不应在paint方法中设置前景和背景。您应该覆盖渲染器的getListCellRendererComponent以进行自定义。如果您具有焦点或选择了焦点,则默认渲染器会更改其方面。如果您不希望这些功能重新实现该方法。

然后,如果向渲染器添加线条边框(setBorder(BorderFactory.createLineBorder(Color.black)),您将看到绘制的内容不是渲染器的一部分,而是组合框本身。所以您可能需要自定义UI

答案 3 :(得分:0)

调用getListCellRendererComponent的swing代码,然后在返回的组件上调用setForegroundsetBackground(取决于是否选择和/或关注组件)。我认为这是针对某些遗留行为的。不幸的是,它违背了我在渲染器中设置它的目的。

我用这种方法取得了一些好成绩:

下面的代码通过覆盖fg / bg setter来做任何事情来绕过改变前景和背景,然后我只是调用超级实现来设置我想要的颜色。

public static class CustomRenderer extends DefaultListCellRenderer {
    public Component getListCellRendererComponent(JList list, Object value,
        int index, boolean isSelected, boolean cellHasFocus) {
        super.getListCellRendererComponent(list, value, index, isSelected,
            cellHasFocus);
        super.setBackground(Color.WHITE);
        super.setForeground(Color.BLACK);     
        return this;
    }
    public void setForeground(Color c) {}
    public void setBackground(Color c) {}
}

<强>附录: 灰色边框可能只是边界。尝试相同的方法,但也覆盖setBorder