Установить прозрачный фон на JList - PullRequest
0 голосов
/ 10 декабря 2018

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

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

enter image description here

Это мой пользовательский класс рендерера 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)) на все компоненты, однако у меня былонет хороших результатов.

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

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

При тестировании новой концепции сначала протестируйте ее, используя стандартные классы 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. Не устанавливайте свойства компонента рендеринга в методе рисования.То есть вы должны установить границы и непрозрачные свойства в конструкторе, если эти значения не изменятся.
  3. Не выполнять ввод-вывод в рендере.Рендерер должен прочитать файлы в конструкторе и сохранить изображение в кеше для быстрого ознакомления.
0 голосов
/ 10 декабря 2018

Я не думаю, что вы хотите делать такого рода изменения внутри средства визуализации ячеек, поскольку оно отвечает за отрисовку ячеек списка, которые по умолчанию не являются непрозрачными, а не самого 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, то его компоненты должны быть прозрачными, но я не уверен, как выпрокручиваю, если вы не видите полосу прокрутки.

...