Java 在JList上设置透明背景
我正在尝试删除(或只是设置不可见)我的JList的背景和边框 当我在其上设置透明颜色时,我的JList背景保持白色 这是我的自定义jcombox渲染器类:Java 在JList上设置透明背景,java,swing,jlist,paintcomponent,jcomponent,Java,Swing,Jlist,Paintcomponent,Jcomponent,我正在尝试删除(或只是设置不可见)我的JList的背景和边框 当我在其上设置透明颜色时,我的JList背景保持白色 这是我的自定义jcombox渲染器类: package Utils.UI.CustomeComboBox; import Parameter.Model.ThemeEnum; import Repository.Parameter.ThemeParameterRepository; import Utils.UI.FileGetter; import Utils.UI.Util
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(新颜色(255,0,0,0))
,但是没有得到好的结果
一种解决方案是调整列表中图像的大小,但我的图像不是矩形的,因此列表背景的角是可见的。我认为您不希望在单元格渲染器中进行这种更改,因为它负责绘制列表单元格,默认情况下列表单元格不是不透明的,而不是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());
}
}
import javax.swing.*;
导入javax.swing.event.ListSelectionEvent;
导入javax.swing.event.ListSelectionListener;
公共类测试{
私有静态void createAndShowGui(){
最终JFrame=新JFrame(“JList测试”);
最终JPanel面板=新JPanel();
String[]listData={“一”、“二”、“三”、“四”、“五”、“六”};
最终JList列表=新JList(listData);
//list.setOpaque(false);
挫折背景(新颜色(0,0,0,0));
addListSelectionListener(新的ListSelectionListener(){
@凌驾
public void值已更改(ListSelectionEvent e){
panel.repaint();
}
});
面板。添加(列表);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(面板);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
调用器(()->createAndShowGui());
}
}
请注意,如果JList由JScrollPane持有,则其组件必须设置为透明,但我不确定如果看不到滚动窗格,您将如何滚动。我认为您不希望在单元格渲染器中进行此类更改,因为它负责绘制默认不不透明的列表单元格,而不是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());
}
}
import javax.swing.*;
导入javax.swing.event.ListSelectionEvent;
导入javax.swing.event.ListSelectionListener;
公共类测试{
私有静态void createAndShowGui(){
最终JFrame=新JFrame(“JList测试”);
最终JPanel面板=新JPanel();
String[]listData={“一”、“二”、“三”、“四”、“五”、“六”};
最终JList列表=新JList(listData);
//list.setOpaque(false);
挫折背景(新颜色(0,0,0,0));
addListSelectionListener(新的ListSelectionListener(){
@凌驾
public void值已更改(ListSelectionEvent e){
panel.repaint();
}
});
面板。添加(列表);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(面板);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
公共静态void main(字符串[]args){
调用器(()->createAndShowGui());
}
}
请注意,如果JList由一个JScrollPane持有,那么它的组件必须设置为透明,但我不确定如果看不到滚动窗格,您将如何滚动。在测试新概念时,首先使用标准JDK类对其进行测试 因此,只需将JList和默认渲染器设置为透明即可:
JList<String> list = new JList<String>(...);
list.setOpaque(false);
DefaultListCellRenderer renderer = new DefaultListCellRenderer();
renderer.setOpaque( false );
list.setCellRenderer( renderer );
不要使用透明颜色设置列表的背景。这是一个已知的Swing问题。有关此问题的更多信息,请参阅
此外,不应在渲染器中更改列表的属性
其他一些评论:
paintComponent(…)
not paint()完成在测试新概念时,首先使用标准JDK类对其进行测试 因此,只需将JList和默认渲染器设置为透明即可:
JList<String> list = new JList<String>(...);
list.setOpaque(false);
DefaultListCellRenderer renderer = new DefaultListCellRenderer();
renderer.setOpaque( false );
list.setCellRenderer( renderer );
不要使用透明颜色设置列表的背景。这是一个已知的Swing问题。有关此问题的更多信息,请参阅
此外,不应在渲染器中更改列表的属性
其他一些评论:
paintComponent(…)
not paint()完成