Цвет раскрывающегося элемента управления и границы в недоступном для редактирования JComboBox - PullRequest
4 голосов
/ 29 декабря 2010

Цвет фона выбранного элемента в недоступном для редактирования JComboBox - синий:

alt text

Я знаю, что вы можете изменить его на другой цвет, например белый, например, с помощью следующего кода :

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 ]

1 голос
/ 27 сентября 2018

Не уверен, что именно ОП пытается достичь, но вот мой рецепт раскраски 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

1 голос
/ 03 февраля 2011

Пара вещей:

  1. Внешний вид выпадающего списка (область отображения, стрелка, раскрывающийся список) зависит от LAF. Ваши скриншоты предлагают WinXP. Если вы должны поддерживать любые другие LAF, обязательно проверьте это, потому что то, что работает для одного LAF, может не работать для другого. Я обнаружил, что это особенно верно для JComboBoxes.

  2. Как предлагает Twister, изменение цвета путем переопределения метода paint (), вероятно, не лучший способ сделать это. Просто установите цвет фона / переднего плана самого списка . Если вы хотите изменить цвет самого выпадающего (мне не ясно, хотите вы этого или нет), добавьте пользовательский рендер, который переопределяет getListCellRendererComponent для установки фона / переднего плана.

    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);
    
0 голосов
/ 03 марта 2011

Код свинга, который вызывает getListCellRendererComponent, затем вызывает setForeground и setBackground на возвращенном компоненте (в зависимости от того, выбран ли компонент и / или находится ли он в фокусе).Я предполагаю, что это для некоторого унаследованного поведения.К сожалению, это побеждает цель моей установки в рендерере.

У меня были некоторые хорошие результаты с этим подходом:

Код ниже обходит изменение переднего плана и фона путем переопределения fg/ bg setters ничего не делает, затем я просто вызываю супер реализации, чтобы установить нужные мне цвета.

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.

0 голосов
/ 10 января 2011

Во-первых, вы не должны устанавливать передний план и фон в методе рисования. Вы должны переопределить getListCellRendererComponent вашего средства визуализации, чтобы настроить его. Рендерер по умолчанию меняет свой аспект, если у вас есть фокус или если он выбран. Если вы не хотите, чтобы эти функции переопределяли метод.

Затем, если вы добавите границу линии к вашему рендереру (setBorder (BorderFactory.createLineBorder (Color.black)), вы увидите, что то, что нарисовано, является не частью вашего рендерера, а самим комбинированным списком. UI

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...