java - 摆动组件的透明度故障
问题描述
我一直在使用 Color(p,p,p,p) 的 JCombobox 的透明度方面遇到问题。一旦我点击它,当光标只在其中一个上时,显示的所有选项似乎都被光标选中了。有时其他按钮出现在透明组件后面,但它们不在它后面。
透明度确实有效,但我不希望它看起来有问题,我一直在尝试将 paintComponents() 方法与填充矩形一起使用,并且它仅适用于 jcombobox 的选项未显示时,它看起来很完美而不是窃听,但是一旦我显示组合框的选项,这些似乎都被选中,并且在它们后面带有其他组件的阴影。有什么方法可以获取包含选项的 jcombobox 的显示组件,并设置一个不透明的背景或其他东西来解决这个问题?
这是面板的代码,其中我有 3 个带有 MyComboBox 的按钮和一个测试类:
//========================== MYCOMBOBOX CLASS ===========================
package views;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComboBox;
import models.EnumModels;
public class MyComboBox<E> extends JComboBox<E> {
public MyComboBox () {
setOpaque(false);
setBackground(new Color(18, 10, 44, 100));
}
protected void paintComponent(Graphics g)
{
g.setColor( getBackground() );
g.fillRect(0, 0, getWidth(), getHeight());
super.paintComponent(g);
}
}
//======================= PANEL WITH MYCOMBOBOX ====================
package views;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import controller.Actions;
import controller.EventsController;
import models.EnumModels;
public class CentralPanel extends JPanel{
MyButton info, add, recent, modelFilter;
boolean bool;
JTextField modelField;
MyComboBox<EnumModels> modelsBox;
public CentralPanel() {
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
setSize(600,845);
setOpaque(false);
setBackground(new Color(18, 10, 44, 100));
setBorder(BorderFactory.createLineBorder(Color.decode("#E80909"), 4, true));
JPanel infoPanel = new JPanel();
infoPanel.setLayout(new BorderLayout());
infoPanel.setBorder(BorderFactory.createEmptyBorder(100, 65, 0, 65));
JPanel addPanel = new JPanel();
addPanel.setLayout(new BorderLayout());
addPanel.setBorder(BorderFactory.createEmptyBorder(100, 65, 0, 65));
JPanel recentPanel = new JPanel();
recentPanel.setLayout(new BorderLayout());
recentPanel.setBorder(BorderFactory.createEmptyBorder(100, 65, 0, 65));
JPanel modelFilterPanel = new JPanel();
modelFilterPanel.setLayout(new BorderLayout());
modelFilterPanel.setBorder(BorderFactory.createEmptyBorder(100, 65, 65, 65));
info = new MyButton();
info.setFont(new Font("Unispace", Font.BOLD, 24));
info.setForeground(Color.decode("#E80909"));
info.setText("Información de Vehículos");
add = new MyButton();
add.setFont(new Font("Unispace", Font.BOLD, 24));
add.setForeground(Color.decode("#E80909"));
add.setText("Agregar Vehículo");
recent = new MyButton();
recent.setFont(new Font("Unispace", Font.BOLD, 24));
recent.setForeground(Color.decode("#E80909"));
recent.setText("Vehículos Recientes");
modelFilter = new MyButton();
modelFilter.setFont(new Font("Unispace", Font.BOLD, 24));
modelFilter.setForeground(Color.decode("#E80909"));
modelFilter.setText("Filtro de Modelo");
modelsBox = new MyComboBox<>();
DefaultComboBoxModel model = new DefaultComboBoxModel<>(EnumModels.values());
modelsBox.setModel(model);
// modelsBox.setBackground(new Color(18, 10, 44, 100));
modelsBox.setForeground(Color.decode("#8A7676"));
modelsBox.setFont(new Font("Unispace", Font.BOLD, 20));
((JLabel)modelsBox.getRenderer()).setHorizontalAlignment(SwingConstants.CENTER);
((JLabel)modelsBox.getRenderer()).setFocusable(false);
// ((JLabel)modelsBox.getRenderer()).setOpaque(false);
// ((JLabel)modelsBox.getRenderer()).setBackground(new Color(18, 10, 44,100));
info.addActionListener(EventsController.getInstance());
info.setActionCommand(Actions.MAIN_INFO.name());
add.addActionListener(EventsController.getInstance());
add.setActionCommand(Actions.MAIN_ADD.name());
recent.addActionListener(EventsController.getInstance());
recent.setActionCommand(Actions.MAIN_RECENT.name());
modelFilter.addActionListener(EventsController.getInstance());
modelFilter.setActionCommand(Actions.MAIN_FILTER.name());
infoPanel.add(info);
infoPanel.setOpaque(false);
addPanel.add(add);
addPanel.setOpaque(false);
recentPanel.add(recent);
recentPanel.setOpaque(false);
modelFilterPanel.add(modelsBox);
modelFilterPanel.setOpaque(false);
add(infoPanel);
add(addPanel);
add(recentPanel);
add(modelFilterPanel);
}
protected void paintComponent(Graphics g)
{
g.setColor( getBackground() );
g.fillRect(0, 0, getWidth(), getHeight());
super.paintComponent(g);
}
///================================ MAIN RUNNER ============================
package test;
import java.awt.Image;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import views.CentralPanel;
public class TestViews extends JFrame {
CentralPanel panel;
public TestViews() {
setExtendedState(MAXIMIZED_BOTH);
setDefaultCloseOperation(EXIT_ON_CLOSE);
panel = new CentralPanel();
add(panel);
setVisible(true);
}
public static void main(String[] args) {
new TestViews();
}
}
//================================ ENUM-COMBOBOX =============================
package models;
public enum EnumModels {
NOVENTA("1990"),NOVENTA_UNO("1991"),NOVENTA_DOS("1992"),NOVENTA_TRES("1993"),NOVENTA_CUATRO("1994"),NOVENTA_CINCO("1995"),NOVENTA_SEIS("1996"),NOVENTA_SIETE("1997"),NOVENTA_OCHO("1998"),NOVENTA_NUEVE("1999"),
DOSMIL_UNO("2001"),DOSMIL_DOS("2002"),DOSMIL_TRES("2003"),DOSMIL_CUATRO("2004"),DOSMIL_CINCO("2005"),DOSMIL_SEIS("2006"),DOSMIL_SIETE("2007"),DOSMIL_OCHO("2008"),DOSMIL_NUEVE("2009"),DOSMIL_DIEZ("2010"),DOSMIL_ONCE("2011"),
DOSMIL_DOCE("2012"),DOSMIL_TRECE("2013"),DOSMIL_CATORCE("2014"),DOSMIL_QUINCE("2015"),DOSMIL_DIEZ_Y_SEIS("2016"),DOSMIL_DIEZ_Y_SIETE("2017"),DOSMIL_DIEZ_Y_OCHO("2018"),DOSMIL_DIEZ_Y_NUEVE("2019"),DOSMIL_VEINTE("2020");
private String year;
public String getYear() {
return this.year;
}
private EnumModels(String year) {
this.year = year;
}
public String toString() {
return year;
}
}
解决方案
当您使用透明背景时,Swing 组件无法正确绘制,因为 Swing 期望组件根据组件的 setOpaque(...) 属性是不透明或不透明的。
如果你想使用透明度,那么你必须手动确保背景是用如下代码绘制的:
JPanel panel = new JPanel()
{
protected void paintComponent(Graphics g)
{
g.setColor( getBackground() );
g.fillRect(0, 0, getWidth(), getHeight());
super.paintComponent(g);
}
};
panel.setOpaque(false); // background of parent will be painted first
panel.setBackground( new Color(255, 0, 0, 20) );
frame.add(panel);
您需要使用透明背景为每个组件自定义绘画。
或者更简单的方法是使用AlphaContainer
,它充当组件的包装面板并为您绘制背景。有关详细信息,请参阅具有透明度的背景。
推荐阅读
- javascript - 保存状态在 React Native 中不能异步工作
- javascript - 使用自定义 NonNullableArrItems 类型将类型转换为 NonNullable 的部分调用
- javascript - 从datalist输入列表如何确定元素的数量
- github - GitHub 和 Fork 问题的可见性更改
- reactjs - 为更新突变解构对象
- ethereum - Web3.js - 错误:返回值无效,它是否耗尽了气体?
- ios - SwiftUI - 计算 ScrollView 中长 GeometryReader 的高度
- apache-spark - 在 pyspark 中读取、转换和输出结果的有效方法
- apache-nifi - Nifi Custom Processor - 未指定传输关系
- debugging - remix ethereum.org 中的调试器将函数返回值显示为“对象”