Reputation: 600
I'm trying to remove (or just to set invisible) the background and the borders of my JList.
When I set a transparent color on it my JList background stays white.
This is my custom jcombox renderer class :
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();
}
}
I tried to put setOpaque(false)
and setBackground(new Color(255, 0, 0, 0))
on every components however I had no good results.
One solution is to resize my images inside the list but my images are not rectangle so the corners of the list background are visible.
Upvotes: 1
Views: 1339
Reputation: 324118
When testing a new concept first test it using the standard JDK classes.
So you can do this by just setting the JList and the default renderer to be transparent:
JList<String> list = new JList<String>(...);
list.setOpaque(false);
DefaultListCellRenderer renderer = new DefaultListCellRenderer();
renderer.setOpaque( false );
list.setCellRenderer( renderer );
This approach will make the list and renderer transparent so all you see is the Border of the selected cell.
Now once you prove the basic concept works, you can create your custom renderer. If it doesn't work then you know the problem is with your custom code.
list.setBackground(new Color(255, 0, 0, 0));
Don't set the background of the list using a transparent color. This is a known Swing issue. See Backgrounds With Transparency for more information on this problem.
Also, you should NOT change the properties of the list in the renderer.
Some other comments:
paintComponent(...)
not paint().Upvotes: 1
Reputation: 285405
I don't think that you want to do this sort of change within the cell renderer since that is responsible for drawing the list cells, which are not opaque by default, and not the JList itself.
Instead why not simply give your JList a transparent background color after creating it?
list.setBackground(new Color(0, 0, 0, 0));
But if you do this, you have to watch for drawing artifacts that can occur when placing drawing on top of opaque items. I found that repainting the container holding the JList can fix this:
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());
}
}
Note that if the JList is held by a JScrollPane then its components must be set to be transparent, but I'm not sure how you'd scroll if you can't see the scrollpane.
Upvotes: 4