Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么添加透明度时透明按钮会显示帧的图像?_Java_Swing_Jbutton_Transparency - Fatal编程技术网

Java 为什么添加透明度时透明按钮会显示帧的图像?

Java 为什么添加透明度时透明按钮会显示帧的图像?,java,swing,jbutton,transparency,Java,Swing,Jbutton,Transparency,我正在为Java应用程序开发GUI,我想要一个背景图像。问题是,我有一种“抽屉”类型,里面装满了按钮,当按钮被选中时,按钮会以红色高位显示 Im使用buttonName.setBackground方法(新颜色(255、102、102、200));同时设置高位按钮和透明度。问题是,尽管该方法可以工作并使按钮透明,但透明显示的是按钮后面框架的随机部分,包括标题、另一个按钮、按钮所在的JScrollPane滚动条等。按钮的文本仍然显示,按钮也可以工作,但是背景显示了来自其他按钮或框架部分的文本 此外,

我正在为Java应用程序开发GUI,我想要一个背景图像。问题是,我有一种“抽屉”类型,里面装满了按钮,当按钮被选中时,按钮会以红色高位显示

Im使用buttonName.setBackground方法(新颜色(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);
        }
    }

}

在另一个例子中,我将透明度应用于整个导航面板,它是一个JLabel。在第一幅图像中,显示的是框架显示时出现的内容,甚至框架的某些部分显示在导航面板下方。在第二个示例中,显示了当我使用滚动条一次时发生的情况

编辑2: 我将所有用作JPanel的JLabel替换为实际的JPanel。不幸的是,这只虫子一直存在。我在主JPanel中添加了一个额外的按钮,之所以这样做是因为我认为错误源于向JScrollPane添加按钮。但问题似乎直接出在我如何实现方法buttonName.setBackground()上

以下是代码的新版本:

在99%的情况下,您在示例应用程序中看到的任何问题都是由于不透明和/或非不透明组件的不正确混合造成的

正如我从代码中看到的,您正在使用
setOpaque(…)
来更改各种组件的不透明度,但是它非常混乱。简而言之,
opaque
属性的作用是什么?每当需要对特定UI元素(面板/标签/按钮等)进行可视化更新时,它会影响Swing重新绘制该元素的方式

例如,当你用鼠标悬停一个按钮时,如果它有一个不同的悬停状态,可能需要重新绘制,无论它是一个图标还是一个稍微/完全不同的样式。这就是不透明度发挥作用的地方-
opaque=true
组件永远不会将重绘调用“在”自身下传递给它们的父组件(用其他/适当的术语)。这意味着,如果面板上有一个不透明按钮,当它变为“悬停”状态时,必须重新绘制该按钮-该按钮将是唯一重新绘制的组件,因为它是不透明的,因此没有理由重新绘制其下方的任何内容,您实际上应该无法看穿它,因此,图形应该用不透明的颜色填充按钮边界内的所有像素

理论上。在实践中,如果您将按钮设置为不透明状态,但使其图形内容保持透明或半透明(这显然是一个错误,但Swing永远不会告诉您这一点),您将看到各种视觉构件,就像您在应用程序中看到的一样。这是由于
Graphics2D
实现经常在(0,0)坐标处执行不同的绘制操作以优化其速度而导致的-了解这一点并不重要,但这也是为什么在组件边界透明时可能会看到其他组件“部分”混合在组件边界中的部分原因。这比这要复杂一点,但这并不重要,因为它只是一个内部的Swing优化

在同一布局上混合
opaque=true
opaque=false
组件也可能导致类似的视觉问题。很可能你的问题也是如此。我确实很快尝试将演示中的所有内容设置为
opaque=false
,它确实解决了问题,但这并不是解决问题的正确方法,尤其是如果您希望保持某些组件的不透明性。这就意味着问题在于在一个容器中混合不同不透明类型的组件

我个人的建议-如果不透明和非不透明组件有轻微重叠的可能(意味着它们的边界将在布局中相交),则不要在一个布局中混合使用不透明和非不透明组件。或者更好——在单个容器中,不要重叠组件。使用多个嵌套容器和适当的非空布局,这也将在将来帮助您轻松修改UI

我可以给你一个简单的例子来说明为什么它不好:

/**
*@作者米克尔·加林
*/
公共类不透明结石
{
公共静态void main(字符串[]args)
{
SwingUtilities.invokeLater(()->{
最终JFrame=新JFrame(“不透明度故障样本”);
//默认为不透明
最终JPanel面板=新JPanel(空);
//默认情况下为不透明,但可能随L&F的不同而不同
最终JButton button1=新JButton(“1111111”);
panel.add(按钮1);
//非不透明,以演示问题
最终JButton按钮2=新JButton(“2222222”);
panel.add(按钮2);
//交叉按钮
按钮1.立根(100、100、150、30);
按钮2.立根(130、115、150、30);
frame.getContentPane().add(面板);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
框架尺寸(500500);
frame.setLocationRelativeTo(空);
frame.setVisible(true);
} );
}
}
从理论上讲,您应该得到的是
按钮1
始终位于顶部(因为它被较早地添加,并且在容器上最后一次绘制),但位于顶部
        panelNav.setBackground(new Color(0, 0, 0, 200));
        panelNav.setOpaque(true);
button2.setOpaque ( false );