简体   繁体   中英

Extending Swing JComboBox to remove unwanted border

I spent the last few hours looking for a solution or at least a decent guide about this issue, but found nothing.

I'm implementing a custom Swing Look and Feel for a small GUI of mine. Up until now I've been using the UIManager.put("key", values); method to good success, but I got stuck when it came to properly modify JComboBoxes.

Using this list I managed to get my jComboBoxes really close to what I want them to look like:

修改了JComboBox

I have two issues with this, a major and a minor one:

  • Major

    在此输入图像描述

    I want the blue shown border gone.

  • Minor

    在此输入图像描述

    I'd really like the black shown border gone.

Apparently no key in the UIDefaults has anything to do with either two borders: they seem somehow hardcoded in the Look and Feel I'm modifying (which should be Metal). I resorted to manually extending the ComboBoxRenderer and managed to come up with this:

package exec.laf.theme;

import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.BasicComboBoxRenderer;


public class ComboBoxRenderer extends BasicComboBoxRenderer {
    private Color background;
    private Color selectionBackground;

    public ComboBoxRenderer() {
        super();

        background = UIManager.getColor("ComboBox.background");
        selectionBackground = UIManager.getColor("ComboBox.selectionBackground");
    }

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        setText((String) value);

        if (isSelected) setBackground(selectionBackground);
        else setBackground(background);

        return this;
    }
}

Where I specify this Renderer every time I create a JComboBox like so:

aComboBox.setRenderer(new ComboBoxRenderer());

obtaining the same look as the non-extended JComboBox.

The problem is that with this extension I can't find a way of touching those borders. Adding setBorder(new EmptyBorder(0, 0, 0, 0)); accomplishes nothing, since it simply adds a border to the listed items.

I checked the source code for javax.swing.plaf.basic.BasicComboBoxRenderer to see if any borders were applied there, but found nothing (the only border there is the one applied to the listed items, that I can override as shown above.

What am I supposed to do? Am I extending the wrong class, or am I missing something else?

The solution I found is:

UIManager.put("ComboBox.borderPaintsFocus", Boolean.TRUE)

This sets a boolean inside the ComboBoxUI that prevents rendering of the focus border, which is the border painted around all buttons when they are focused. Its style is dependent on your look and feel.

To remove the black border of comboBox PopUp,

Object child = comboBox.getAccessibleContext().getAccessibleChild(0);
BasicComboPopup popup = (BasicComboPopup)child;
popup.setBorder(BorderFactory.createEmptyBorder());

If i understoud, your problem is in generally how to use extended class from BasicComboBoxRenderer. So here a simple code to explain you how to use it:

public class RenderComboBox extends BasicComboBoxRenderer {

    Color selectedBackground;
    Color selectedForground;
    Color background;
    Color forground;

    public RenderComboBox() {
        setOpaque(true);        
        background = new Color(37, 37, 37);
        selectedBackground = new Color(93, 93, 93);
        forground = Color.WHITE;
        selectedForground = forground;
    }

    @Override
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {

        if (isSelected) {
            setBackground(selectedBackground);
            setForeground(selectedForground);
        } else {
            setBackground(background);
            setForeground(forground);
        }
        setFont(list.getFont());
        if (value == null) {
            setText("");
        } else {
            setText(value.toString());
        }
        return this;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setLayout(null);
        frame.setPreferredSize(new Dimension(200, 170));

        JComboBox<String> combobox = new JComboBox<>();
        combobox.setRenderer(new RenderComboBox());
        combobox.setBounds(50, 50, 100, 20);
        combobox.addItem("TEST");
        combobox.addItem("REVERT");

        frame.add(combobox);
        frame.pack();
        frame.setVisible(true);

    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM