Установить прозрачный фон в JList

Я пытаюсь удалить (или просто сделать невидимым) фон и границы моего JList.

Когда я устанавливаю для него прозрачный цвет, мой фон JList остается белым.

Установить прозрачный фон в JList

Это мой собственный класс рендерера jcombox:

package Utils.UI.CustomeComboBox;

import Parameter.Model.ThemeEnum;
import Repository.Parameter.ThemeParameterRepository;
import Utils.UI.FileGetter;
import Utils.UI.Utils;

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

public class CustomComboBoxRenderer extends BasicComboBoxRenderer {

    private Image backgroundImage;
    private Font font;
    private final static int WIDTH = 190;
    private final static int HEIGHT = 49;

    public CustomComboBoxRenderer() {
        super();

        this.setOpaque(false);
        this.setHorizontalTextPosition(AbstractButton.CENTER);
        this.setVerticalAlignment(AbstractButton.CENTER);
        this.setPreferredSize(new Dimension(CustomComboBoxRenderer.WIDTH, CustomComboBoxRenderer.HEIGHT));
        this.font = FileGetter.getFont().deriveFont(Utils.DEFAULT_SIZE_BUTTON_TEXT);
    }

    public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)
    {
        super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        list.setOpaque(false);
        list.setBackground(new Color(255, 0, 0, 0));
        list.setBorder(BorderFactory.createEmptyBorder());
        if (index == -1 || isSelected) {
            this.backgroundImage = FileGetter.getImage("_button13.png");
        } else {
            this.backgroundImage = FileGetter.getImage("_button02.png");
        }

        return this;
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;

        // background image
        g2d.drawImage(this.backgroundImage, 0, 0, this);

        // text
        g2d.setFont(this.font);
        g2d.setColor((Color) ThemeParameterRepository.getColor(ThemeEnum.SECOND_COLOR).getValue());
        FontMetrics fontMetrics = g.getFontMetrics(this.font);
        g2d.drawString(
            this.getText(),
            (CustomComboBoxRenderer.WIDTH - fontMetrics.stringWidth(this.getText())) / 2,
            ((CustomComboBoxRenderer.HEIGHT - fontMetrics.getHeight()) / 2) + fontMetrics.getAscent()
        );

        g2d.finalize();
    }
}

Я пытался поставить setOpaque(false) и setBackground(new Color(255, 0, 0, 0)) на все компоненты, но у меня не было хороших результатов.

Одно из решений - изменить размер моих изображений внутри списка, но мои изображения не прямоугольные, поэтому углы фона списка видны.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
735
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я не думаю, что вы хотите делать такого рода изменения в рендерере ячеек, поскольку он отвечает за отрисовку ячеек списка, которые по умолчанию не являются непрозрачными, а не самого JList.

Вместо этого почему бы просто не дать вашему JList прозрачный цвет фона после его создания?

 list.setBackground(new Color(0, 0, 0, 0));

Но если вы это сделаете, вам нужно будет следить за артефактами рисования, которые могут возникнуть при размещении рисунка поверх непрозрачных элементов. Я обнаружил, что перекраска контейнера, содержащего JList, может исправить это:

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class JListTest {


    private static void createAndShowGui() {
        final JFrame frame = new JFrame("JList Test");
        final JPanel panel = new JPanel();

        String[] listData = {"One", "Two", "Three", "Four", "Five", "Six"};
        final JList<String> list = new JList<>(listData);
        // list.setOpaque(false);
        list.setBackground(new Color(0, 0, 0, 0));
        list.addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                panel.repaint();
            }
        });

        panel.add(list);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

Обратите внимание, что если JList удерживается JScrollPane, его компоненты должны быть прозрачными, но я не уверен, как вы будете прокручивать, если не видите полосу прокрутки.

При тестировании новой концепции сначала проверьте ее с помощью стандартных классов JDK.

Таким образом, вы можете сделать это, просто установив JList и средство визуализации по умолчанию, чтобы они были прозрачными:

JList<String> list = new JList<String>(...);
list.setOpaque(false);
DefaultListCellRenderer renderer = new DefaultListCellRenderer();
renderer.setOpaque( false );
list.setCellRenderer( renderer );

Такой подход сделает список и средство визуализации прозрачными, поэтому все, что вы видите, - это граница выбранной ячейки.

Теперь, когда вы докажете, что основная концепция работает, вы можете создать собственное средство визуализации. Если это не сработает, значит, проблема в вашем собственном коде.

list.setBackground(new Color(255, 0, 0, 0));

Не устанавливайте фон списка прозрачным цветом. Это известная проблема Swing. См. Фоны с прозрачностью для получения дополнительной информации об этой проблеме.

Кроме того, вам НЕ следует изменять свойства списка в рендерере.

Некоторые другие комментарии:

  1. Пользовательское рисование выполняется переопределением paintComponent(...) not paint ().
  2. Не устанавливайте свойства компонента рендеринга в методе рисования. То есть вы должны установить свойства border и opaque в конструкторе, если эти значения не изменятся.
  3. Не выполняйте ввод-вывод в рендерере. Средство визуализации должно читать файлы в конструкторе и сохранять изображение в кеше для быстрой справки.

Другие вопросы по теме