我正在为一个Java应用程序开发一个图形用户界面,我想有一个背景图像。问题是我有一种装满按钮的“抽屉”,当被选中时,按钮会以红色高亮显示。
我正在使用方法按钮名称。挫折背景(新颜色(255、102、102、200));同时设置高位按钮和透明度。问题是,尽管该方法可以工作并透明按钮,但透明度显示了按钮后面框架的随机部分,即标题、另一个按钮、按钮所在的JScrollPane滚动条等。按钮的文本仍然显示,按钮也可以工作,但背景显示了来自其他按钮或框架部分的文本。
此外,我意识到,如果我单击一个按钮并将鼠标多次移到所选按钮上,透明度开始累积,直到变成纯色。
package buttonsbug;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
/**
*
* @author F&H
*/
public class ButtonsBug extends JFrame implements ActionListener {
private ArrayList<JButton> botones;
private JLabel panelPrin, panelNav, panelUser, panelImgUser, nombre, puesto;
private JButton logout, planDis, consuEmpleados, funConsultarPiezas, btnCalidad, compraMat, soySuper, histProy, crearProyecto, clientes, adminConsProye;
private JPanel buttonScroll;
private JScrollPane navScroll;
private BufferedImage img;
private Dimension screenSize;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new ButtonsBug().setVisible(true);
} catch (Exception e) {
System.out.println(e.getMessage());
System.exit(0);
}
}
});
}
public ButtonsBug() {
botones = new ArrayList<>();
screenSize = Toolkit.getDefaultToolkit().getScreenSize();
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setSize(ajustarDimensiones(1400), ajustarDimensiones(800));
setContentPane(panelPrin = new JLabel());
panelPrin.setSize(ajustarDimensiones(1400), ajustarDimensiones(800));
try {
img = ImageIO.read(new File("src/tw3.png"));
Image dimg1 = img.getScaledInstance(panelPrin.getWidth(), panelPrin.getHeight(), Image.SCALE_SMOOTH);
ImageIcon imageIcon = new ImageIcon(dimg1);
panelPrin.setIcon(imageIcon);
} catch (IOException z) {
System.out.println(z.getMessage());
JOptionPane.showMessageDialog(this, "¡Error en la lectura de imagen!", "Error", JOptionPane.ERROR_MESSAGE);
}
panelPrin.setBackground(java.awt.Color.white);
panelPrin.add(panelNav = new JLabel());
// panelPrin.setOpaque(true);
// panelNav.setOpaque(true);
panelNav.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
// panelNav.setBackground(new Color(0, 0, 0, 150));
panelNav.setBounds(0, 0, ajustarDimensiones(305), ajustarDimensiones(771));
panelNav.add(panelUser = new JLabel());
panelNav.add(logout = new JButton());
logout.setContentAreaFilled(false);
// logout.setOpaque(true);
// panelUser.setOpaque(true);
panelUser.setBounds(ajustarDimensiones(1), ajustarDimensiones(1), ajustarDimensiones(303), ajustarDimensiones(88));
panelUser.add(panelImgUser = new JLabel());
panelUser.add(nombre = new JLabel());
panelUser.add(puesto = new JLabel());
nombre.setText("Wil Fonseca");
puesto.setText("Production manager");
nombre.setBounds(ajustarDimensiones(55), ajustarDimensiones(25), ajustarDimensiones(245), ajustarDimensiones(20));
puesto.setBounds(ajustarDimensiones(55), ajustarDimensiones(45), ajustarDimensiones(245), ajustarDimensiones(20));
nombre.setFont(new java.awt.Font("Arial", 1, ajustarDimensiones(14)));
puesto.setFont(new java.awt.Font("Arial", 1, ajustarDimensiones(12)));
nombre.setForeground(Color.white);
puesto.setForeground(Color.white);
logout.setText("Logout");
logout.setFont(new java.awt.Font("Arial", 1, ajustarDimensiones(34)));
logout.setBounds(ajustarDimensiones(1), ajustarDimensiones(691), ajustarDimensiones(303), ajustarDimensiones(88));
logout.setBackground(Color.white);
logout.setForeground(Color.red);
logout.addActionListener(this);
logout.setBorder(null);
logout.setBorderPainted(false);
logout.setFocusPainted(false);
panelImgUser.setBounds(ajustarDimensiones(3), ajustarDimensiones(24), ajustarDimensiones(40), ajustarDimensiones(40));
try {
img = ImageIO.read(new File("src/Usuario.png"));
Image dimg1 = img.getScaledInstance(panelImgUser.getWidth(), panelImgUser.getHeight(), Image.SCALE_SMOOTH);
ImageIcon imageIcon = new ImageIcon(dimg1);
panelImgUser.setIcon(imageIcon);
} catch (IOException z) {
System.out.println(z.getMessage());
}
setTitle("ButtonsBug");
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
buttonGenerator();
}
public int ajustarDimensiones(int coo) {
int newC = 0;
double res = (screenSize.getHeight());
float newRes;
if (res < 1080) {
if (coo == 1400) {
return 1208;
} else if (coo == 800) {
return 680;
}
}
if (coo == 0) {
return newC;
} else {
if (res < 1080) {
newRes = (918f / 1080f);
if (coo == 305) {
newC = (int) (newRes * coo) - 1;
} else if (coo == 90) {
newC = (int) (newRes * coo) - 1;
} else if (coo == 224) {
newC = (int) (newRes * coo) - 1;
} else if (coo == 601) {
newC = (int) (newRes * coo) + 3;
} else if (coo == 1066) {
newC = (int) (newRes * coo) - 1;
} else if (coo == 1474 || coo == 1576) {
newC = (int) (newRes * coo) + 1;
} else if (coo == 1059) {
newC = (int) (newRes * coo) - 10;
} else if (coo == 1095) {
newC = (int) (newRes * coo) + 14;
} else {
newC = (int) (newRes * coo);
}
} else {
newRes = (float) (res / 1080f);
newC = (int) (newRes * coo);
}
if (newC < 0) {
newC = 1;
}
}
return newC;
}
public void buttonGenerator() {
int y = 0;
panelNav.add(navScroll = new JScrollPane(buttonScroll = new JPanel(), JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
navScroll.setBorder(BorderFactory.createEmptyBorder());
navScroll.setBounds(ajustarDimensiones(1), ajustarDimensiones(90), ajustarDimensiones(303), ajustarDimensiones(600));
// navScroll.setBackground(Color.white);
navScroll.setOpaque(false);
navScroll.getVerticalScrollBar().setUnitIncrement(30);
navScroll.setPreferredSize(new Dimension(ajustarDimensiones(305), ajustarDimensiones(601)));
// buttonScroll.setBackground(Color.white);
buttonScroll.setPreferredSize(new Dimension(ajustarDimensiones(305), ajustarDimensiones(601)));
buttonScroll.setLayout(null);
navScroll.setViewportView(buttonScroll);
buttonScroll.setOpaque(false);
navScroll.getViewport().setOpaque(false);
buttonScroll.add(funConsultarPiezas = new JButton());
funConsultarPiezas.setContentAreaFilled(false);
// funConsultarPiezas.setOpaque(true);
funConsultarPiezas.setText("Consultar pieza");
funConsultarPiezas.setFont(new java.awt.Font("Arial", 1, ajustarDimensiones(30)));
funConsultarPiezas.setBounds(ajustarDimensiones(1), ajustarDimensiones(0), ajustarDimensiones(301), ajustarDimensiones(80));
// funConsultarPiezas.setBackground(java.awt.Color.white);
funConsultarPiezas.setForeground(Color.white);
funConsultarPiezas.addActionListener(this);
funConsultarPiezas.setBorder(null);
funConsultarPiezas.setBorderPainted(false);
funConsultarPiezas.setFocusPainted(false);
botones.add(funConsultarPiezas);
y += 81;
buttonScroll.add(btnCalidad = new JButton());
btnCalidad.setContentAreaFilled(false);
// btnCalidad.setOpaque(true);
btnCalidad.setText("Quality Check");
btnCalidad.setBounds(ajustarDimensiones(1), ajustarDimensiones(y), ajustarDimensiones(301), ajustarDimensiones(80));
btnCalidad.setFont(new java.awt.Font("Arial", 1, ajustarDimensiones(30)));
// btnCalidad.setBackground(Color.white);
btnCalidad.setForeground(Color.white);
btnCalidad.addActionListener(this);
btnCalidad.setBorder(null);
btnCalidad.setBorderPainted(false);
btnCalidad.setFocusPainted(false);
botones.add(btnCalidad);
y += 81;
buttonScroll.add(planDis = new JButton());
planDis.setContentAreaFilled(false);
// planDis.setOpaque(true);
planDis.setText("Diseño y planear");
planDis.setBounds(ajustarDimensiones(1), ajustarDimensiones(y), ajustarDimensiones(301), ajustarDimensiones(80));
planDis.setFont(new java.awt.Font("Arial", 1, ajustarDimensiones(30)));
// planDis.setBackground(Color.white);
planDis.setForeground(Color.white);
planDis.addActionListener(this);
planDis.setBorder(null);
planDis.setBorderPainted(false);
planDis.setFocusPainted(false);
botones.add(planDis);
y += 81;
buttonScroll.add(compraMat = new JButton());
compraMat.setContentAreaFilled(false);
// compraMat.setOpaque(true);
compraMat.setText("Compra Material");
compraMat.setBounds(ajustarDimensiones(1), ajustarDimensiones(y), ajustarDimensiones(301), ajustarDimensiones(80));
compraMat.setFont(new java.awt.Font("Arial", 1, ajustarDimensiones(30)));
//compraMat.setBackground(Color.white);
compraMat.setForeground(Color.white);
compraMat.addActionListener(this);
compraMat.setBorder(null);
compraMat.setBorderPainted(false);
compraMat.setFocusPainted(false);
botones.add(compraMat);
y += 81;
buttonScroll.add(soySuper = new JButton());
soySuper.setContentAreaFilled(false);
// soySuper.setOpaque(true);
soySuper.setText("Liberar piezas");
soySuper.setBounds(ajustarDimensiones(1), ajustarDimensiones(y), ajustarDimensiones(301), ajustarDimensiones(80));
soySuper.setFont(new java.awt.Font("Arial", 1, ajustarDimensiones(30)));
//soySuper.setBackground(Color.white);
soySuper.setForeground(Color.white);
soySuper.addActionListener(this);
soySuper.setBorder(null);
soySuper.setBorderPainted(false);
soySuper.setFocusPainted(false);
botones.add(soySuper);
y += 81;
buttonScroll.add(crearProyecto = new JButton());
crearProyecto.setContentAreaFilled(false);
// crearProyecto.setOpaque(true);
crearProyecto.setText("Crear proyecto");
crearProyecto.setBounds(ajustarDimensiones(1), ajustarDimensiones(y), ajustarDimensiones(301), ajustarDimensiones(80));
crearProyecto.setFont(new java.awt.Font("Arial", 1, ajustarDimensiones(30)));
//crearProyecto.setBackground(Color.white);
crearProyecto.setForeground(Color.white);
crearProyecto.addActionListener(this);
crearProyecto.setBorder(null);
crearProyecto.setBorderPainted(false);
crearProyecto.setFocusPainted(false);
botones.add(crearProyecto);
y += 81;
buttonScroll.add(clientes = new JButton());
clientes.setContentAreaFilled(false);
// clientes.setOpaque(true);
clientes.setText("Clientes");
clientes.setBounds(ajustarDimensiones(1), ajustarDimensiones(y), ajustarDimensiones(301), ajustarDimensiones(80));
clientes.setFont(new java.awt.Font("Arial", 1, ajustarDimensiones(30)));
//clientes.setBackground(Color.white);
clientes.setForeground(Color.white);
clientes.addActionListener(this);
clientes.setBorder(null);
clientes.setBorderPainted(false);
clientes.setFocusPainted(false);
botones.add(clientes);
y += 81;
buttonScroll.add(adminConsProye = new JButton());
adminConsProye.setContentAreaFilled(false);
// adminConsProye.setOpaque(true);
adminConsProye.setText("Consultar proyectos");
adminConsProye.setBounds(ajustarDimensiones(1), ajustarDimensiones(y), ajustarDimensiones(301), ajustarDimensiones(80));
adminConsProye.setFont(new java.awt.Font("Arial", 1, ajustarDimensiones(26)));
//adminConsProye.setBackground(Color.white);
adminConsProye.setForeground(Color.white);
adminConsProye.addActionListener(this);
adminConsProye.setBorder(null);
adminConsProye.setBorderPainted(false);
adminConsProye.setFocusPainted(false);
botones.add(adminConsProye);
y += 81;
buttonScroll.add(histProy = new JButton());
histProy.setText("Historial");
histProy.setContentAreaFilled(false);
// histProy.setOpaque(true);
histProy.setBounds(ajustarDimensiones(1), ajustarDimensiones(y), ajustarDimensiones(301), ajustarDimensiones(80));
histProy.setFont(new java.awt.Font("Arial", 1, ajustarDimensiones(30)));
//histProy.setBackground(Color.white);
histProy.setForeground(Color.white);
histProy.addActionListener(this);
histProy.setBorder(null);
histProy.setBorderPainted(false);
histProy.setFocusPainted(false);
botones.add(histProy);
y += 81;
buttonScroll.add(consuEmpleados = new JButton());
consuEmpleados.setText("Trabajadores");
consuEmpleados.setContentAreaFilled(false);
// consuEmpleados.setOpaque(true);
consuEmpleados.setBounds(ajustarDimensiones(1), ajustarDimensiones(y), ajustarDimensiones(301), ajustarDimensiones(80));
consuEmpleados.setFont(new java.awt.Font("Arial", 1, ajustarDimensiones(30)));
//consuEmpleados.setBackground(Color.white);
consuEmpleados.setForeground(Color.white);
consuEmpleados.addActionListener(this);
consuEmpleados.setBorder(null);
consuEmpleados.setBorderPainted(false);
consuEmpleados.setFocusPainted(false);
botones.add(consuEmpleados);
y += 81;
buttonScroll.setPreferredSize(new Dimension(ajustarDimensiones(305), ajustarDimensiones(y)));
}
public void botonSeleccionado(JButton but) {
for (JButton b : botones) {
if (b.getText().equalsIgnoreCase(but.getText())) {
b.setOpaque(true);
b.setBackground(new Color(255, 102, 102, 200));
b.setForeground(Color.white);
} else {
b.setOpaque(false);
//b.setBackground(Color.white);
b.setForeground(Color.white);
}
b.revalidate();
b.repaint();
}
}
@Override
public void actionPerformed(ActionEvent ae) {
JButton obj = (JButton) ae.getSource();
if (obj != logout) {
botonSeleccionado(obj);
}
}
}
如果有人知道如何制作一个干净的透明按钮,我将非常感谢您的帮助。
我在这里留下源代码和我正在使用的测试图像。https://drive.google.com/file/d/1l8R52WTDyP93L0UhTNd3oorD7Qhv-TcP/view?usp=sharing
在这张图片中,你可以看到我有3种错误,在第一个中,你可以看到背景中有另一个按钮,滚动条显示在按钮的左侧。在第二个中,它是导航面板的标题。在第三个中,我多次将鼠标放在seelcted按钮上,它变成了纯色而不是透明的。
编辑:
如果我将错误应用于导航面板,我决定检查它是否仍然存在,因为当应用程序完成时,它也必须是透明的。所以我在上面代码的第82行和83行中添加了以下代码行:
panelNav.setBackground(new Color(0, 0, 0, 200));
panelNav.setOpaque(true);
在另一幅图像中,我将透明度应用于整个导航面板,它是一个JLabel。在第一个图像中,显示了显示框架时显示的内容,甚至框架的某些部分也显示在导航面板下方。第二个例子显示了当我使用滚动条一次时会发生什么。
编辑2:我替换了所有用作实际JPanel的JLabel。可悲的是,错误仍然存在。我在主JPanel中添加了一个额外的按钮,我这样做是因为我认为错误源于向JScrollPane添加按钮。但是问题似乎直接在于我如何实现方法按钮ame.set背景()。
以下是代码的新版本:https://drive.google.com/file/d/1PuHMkEYNbBoafqs5XiyUaeCkIyXfnHFJ/view?usp=sharing
在99%的情况下,您发布的示例应用程序中出现的任何问题都是由于不透明和/或非不透明组件的错误混合造成的。
正如我从代码中看到的,您正在使用setOpaque(…) 更改各种组件的不透明度,但它非常混乱。简而言之,不透明属性的作用是:每当需要对特定UI元素(面板/标签/按钮等)进行视觉更新时,它会影响Swing重新绘制该元素的方式。
例如,当你用鼠标悬停一个按钮时,如果它有不同的悬停状态,可能需要重新绘制,无论它只是一个图标还是一个稍微/完全不同的样式。这就是不透明度发挥作用的地方-opaque=true
组件永远不会将重绘调用“在”自身下传递(用其他/适当的术语-传递给其父组件)。这意味着,如果你在面板上有一个不透明的按钮,当它变为“悬停”状态时,必须对其进行重新绘制-该按钮将是唯一被重新绘制的组件,因为它是不透明的,因此没有理由对其下的任何内容进行重新绘制,你实际上应该无法看穿它,因此图形应该用不透明的颜色填充该按钮范围内的所有像素。
理论上。在实践中,如果您将按钮设置为不透明状态,但使其图形内容保持透明或半透明(这显然是一个错误,但Swing永远不会告诉您),您最终会看到各种视觉瑕疵,就像您在应用程序中看到的一样。这是由于图形2D实现经常在(0,0)坐标下执行不同的绘制操作以优化其速度而导致的-这一点并不重要,但这也是为什么当组件边界是透明的时,您可能会看到其他组件“部分”混合在组件边界中的部分原因。这比这要复杂一点,但它实际上并不重要,因为它只是一个内部的摆动优化。
在同一布局上混合组件也可能会导致类似的视觉问题。你的问题很可能也是这样。我很快尝试将演示中的所有内容设置为“不透明=假”,它确实解决了这个问题,但这并不是解决问题的正确方法,尤其是如果您想保持某些组件不透明的话。这只是意味着问题在于在单个容器中混合具有不同不透明类型的组件。
我个人的建议是——如果不透明和非不透明组件有一点点重叠的机会,就不要在一个布局中混合它们(这意味着它们的边界将在布局中相交)。或者更好的是——不要在单个容器中重叠组件。使用多个嵌套容器和适当的非空布局,这也将有助于你将来轻松修改你的用户界面。
我可以给你举一个简单的例子来说明为什么它不好:
/**
* @author Mikle Garin
*/
public class OpacityGlitch
{
public static void main ( String[] args )
{
SwingUtilities.invokeLater ( () -> {
final JFrame frame = new JFrame ( "Opacity glitch sample" );
// Opaque by default
final JPanel panel = new JPanel ( null );
// Opaque by default, but might vary with L&F
final JButton button1 = new JButton ( "1111111" );
panel.add ( button1 );
// Non-opaque to demonstrate the problem
final JButton button2 = new JButton ( "2222222" );
panel.add ( button2 );
// Intersecting buttons
button1.setBounds ( 100, 100, 150, 30 );
button2.setBounds ( 130, 115, 150, 30 );
frame.getContentPane ().add ( panel );
frame.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
frame.setSize ( 500, 500 );
frame.setLocationRelativeTo ( null );
frame.setVisible ( true );
} );
}
}
从理论上讲,你应该得到的是按钮1始终位于顶部(因为它被较早地添加并且最后被绘制在容器上),但在实践中,如果你尝试悬停其中一个按钮,哪个按钮完全可见并且位于另一个按钮的顶部会发生变化。这是因为这两个按钮都是不透明的,并且重新绘制调用不会经过按钮组件到达其容器以及与它们进一步相交的任何组件。为了解决这个特殊情况,使按钮2非不透明就足够了,因为它应该始终位于按钮1下方,如果它是非不透明的,它将安全地将重新绘制调用至少传递给它的容器:
button2.setOpaque ( false );
尽管我个人建议在这种情况下使所有相关组件不透明,以避免在将来或由于任何用户交互而更改组件顺序时出现其他可能的问题-例如,应用程序中的滚动条就是一个主要示例。尽管如此,容器不必是非不透明的,因为它将在放置在其中的组件之间正确地传递重新绘制调用,并将正确地重新绘制自身。
一旦将我上面示例中的按钮更改为非不透明按钮,由于正确处理了重新绘制,问题将消失。
对于Swing的初学者来说,这可能是一个复杂的主题,但我强烈建议完全理解为什么以及如何发生这样的事情,否则一旦您的应用程序变得更大,它将成为您未来的一个巨大问题。
#klem1,#klem2 { opacity:0.4; filter:alpha(opacity=40); /* For IE8 and earlier */ } #klem1:hover,#klem2:hover { opacity:1.0; filter:alpha(opacity=100); /* For IE8 and earlier */ } div.background { widt
问题内容: 所以我有两个图像,我想显示在彼此的顶部。这个 上面的图像应该是透明的,这样底部的图像是透明的 可见。 Here is my code so far: With the face in the bottom and the eyes on top. 问题答案: Try this 我没有你的两个源图像,所以我不能确定它将与工作 他们。如有任何问题,请提供两者的原件。
问题内容: CSS3动画出现问题。 仅当我删除的更改时,此代码才有效。 我想在悬停后立即更改显示,但不透明度应使用过渡进行更改。 问题答案: 我改变了一点,但结果很漂亮。 谢谢大家
现在的问题是:我有一个由第三方创建的XFA表单,我想按原样使用它。我可以通过以下方式生成带有填充字段的PDF: 我想做的只是在第二页上盖上一个图像/水印,它有一个包含多个字段的表单。我正在冲压的“草稿”png图像有一个透明的背景,所以如果覆盖工作,图像背景应该使衬底出现,看起来像图像文本坐在pdf页面的顶部。 如果这不是一个XFA表单,我想要完成的将是微不足道的。我只需要使用iText的pdfSt
我试着用特定的透明颜色在Android画布中显示一个jpg。它与png配合得很好,我也知道如何用java将jpg转换为png,所以最后我在文件系统上有了一个新的png文件。 现在我的问题是:有没有办法从文件系统读取jpg文件,在运行时设置透明颜色(转换为png)并在运行时显示图像? 附加注释:我尝试在自定义视图中使用ondraw方法和drawbitmap来实现这一点。我不能使用imageview:
前面在学习《 CSS颜色》时我们已经了解,通过 rgba()、hsla() 可以设置颜色的透明度,但是它们只能在定义颜色的同时设置透明度,无法对图像或者其它元素设置透明度。 CSS 中提供了一个 opacity 属性用来设置元素的透明度,它不仅对颜色有效,对图像或者页面中其它的元素也有效。其语法格式如下: opacity: number; 其中 number 为一个 0~1 之间的浮点数(小数),