简体   繁体   English

当我使框架的背景透明时,ImageIcon停止更改吗?

[英]ImageIcon stops changing when I make my frame's background transparent?

For some reason, when I run "frame.setBackground(new Color(1.0f,1.0f,1.0f,0.0f));", then change my button's icon and repaint (even with paintImmediately) the icon of my button refuses to change. 由于某种原因,当我运行“ frame.setBackground(new Color(1.0f,1.0f,1.0f,0.0f));”时,更改我按钮的图标并重新绘制(即使立即使用paint)我按钮的图标也拒绝更改。 Just commenting out that line has it working again, but I kinda want that to work. 只是注释掉该行,它可以再次工作,但是我有点希望它能工作。

public static void main (String[] args) throws Exception
{
    robot = new Robot();
    frame = new JDialog();

    frame.setUndecorated(true);
    frame.setSize(59,61);
    frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice defaultScreen = ge.getDefaultScreenDevice();
    Rectangle rect = defaultScreen.getDefaultConfiguration().getBounds();
    int x = (int) rect.getMaxX() - frame.getWidth() - 17;
    int y = (int) rect.getMaxY() - frame.getHeight() - 40;
    frame.setLocation(x, y);
    frame.setAlwaysOnTop(true);
    frame.setBackground(new Color(1.0f,1.0f,1.0f,0.0f));

    panel = new JPanel(new BorderLayout());
    panel.setBackground(new Color(1.0f,1.0f,1.0f,0.0f));
    frame.add(panel);

    InputStream in = HelloWorld.class.getResourceAsStream("/Working/mic2.png");
    notRecording = new ImageIcon(ImageIO.read(in));
    in = HelloWorld.class.getResourceAsStream("/Working/mic3.png");
    recording = new ImageIcon(ImageIO.read(in));
    button = new JButton(notRecording);
    button.setContentAreaFilled(false);
    button.setBorder(BorderFactory.createEmptyBorder());
    panel.add(button);

    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {
            try
            {
                record();
            }
            catch(Exception ex)
            {
                ex.printStackTrace();
                System.out.println("Exception");
            }
        }
    });

    frame.setVisible(true);

}

When I later run 当我以后跑步时

button.setIcon(recording);
button.paintImmediately(button.getBounds());

Nothing happens. 什么都没发生。

Edit: I've read over the other thread, and checked the answer they provided, but I can't seem to find any other source that verifies SWING can't handle alpha values, and in fact most sources recommend it. 编辑:我已经阅读了另一个线程,并检查了它们提供的答案,但是我似乎找不到任何其他可以验证SWING无法处理alpha值的来源,并且实际上大多数来源都推荐这样做。 Additionally, calling setOpaque according to setOpaque(true/false); 另外,根据setOpaque(true / false)调用setOpaque ; Java seems to imply that using setOpaque is a much more complex concept than just transparency. Java似乎暗示使用setOpaque是一个比透明性更复杂的概念。 Additionally, replacing setBackground with setOpaque doesn't work, so I don't think the thread should be closed due to the other thread covering a similar material. 另外,用setOpaque替换setBackground无效,因此我不认为该线程应该关闭,因为另一个线程覆盖了类似的材料。

Here's an example of what isn't working for me. 这是一个不适用于我的示例。 In theory, this would leave just the text, or at least only the section that the button occupies of the dialog remaining visible, with the rest not opaque. 从理论上讲,这将仅保留文本,或者至少仅保留对话框按钮所占的部分可见,其余部分则不透明。

import javax.swing.*;
import java.awt.*;

public class RunnableExample
{
    public static void main(String[] args)
    {
        JDialog dialog = new JDialog();
        dialog.setUndecorated(true);
        dialog.setSize(59,61);
        dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        dialog.setAlwaysOnTop(true);
        dialog.getRootPane().setOpaque(false);

        JPanel panel = new JPanel();
        panel.setOpaque(false);
        dialog.add(panel);

        JButton button = new JButton("test");
        button.setContentAreaFilled(false);
        button.setBorderPainted(false);
        button.setOpaque(false);
        panel.add(button);

        dialog.setVisible(true);
    }
}

To make a window transparent, you must use setBackground (on an instance of window class, like JFrame or JDialog) and pass it a transparent color ( new Color(0, 0, 0, 0))`), this is the ONLY time you can use a alpha based color on a Swing component. 要使窗口透明,必须使用setBackground (在窗口类的实例上,例如JFrameJDialog) and pass it a transparent color ( new Color(0,0,0,0))`),这是唯一的时间您可以在Swing组件上使用基于alpha的颜色。

Swing doesn't know how to paint components with a alpha based color, it only knows how to deal with fully transparent or fully opaque components, which is controlled via setOpaque , for example... Swing不知道如何用基于Alpha的颜色绘制组件,它只知道如何处理完全透明或完全不透明的组件,例如,可以通过setOpaque控制...

我是空白

import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.WindowConstants;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JDialog dialog = new JDialog();
                dialog.setUndecorated(true);
                dialog.setBackground(new Color(0, 0, 0, 0));
                dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
                dialog.setAlwaysOnTop(true);
                dialog.getRootPane().setOpaque(false);

                JPanel panel = new JPanel();
                panel.setOpaque(false);
                dialog.add(panel);

                JButton button = new JButton("test");
                button.setContentAreaFilled(false);
                button.setBorderPainted(false);
                button.setOpaque(false);
                panel.add(button);

                dialog.pack();
                dialog.setLocationRelativeTo(null);
                dialog.setVisible(true);
            }
        });
    }

}

I can further prove it by adding 我可以通过添加进一步证明

panel.setBorder(new CompoundBorder(new LineBorder(Color.RED), new EmptyBorder(10, 10, 10, 10)));

to the code, which produces 代码,产生

还是空白

The red line is actually the output of the frame (technically the panel, but for this, it's the same thing) 红线实际上是框架的输出(从技术上讲是面板,但与此相同)

And because there's something wrong with the button/icons... 而且因为按钮/图标有问题...

播放图示

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.WindowConstants;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JDialog dialog = new JDialog();
                dialog.setUndecorated(true);
                dialog.setBackground(new Color(0, 0, 0, 0));
                dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
                dialog.setAlwaysOnTop(true);
                dialog.getRootPane().setOpaque(false);

                JPanel panel = new JPanel();
                panel.setOpaque(false);
                dialog.add(panel);

                try {
                    JButton button = new JButton(new ImageIcon(ImageIO.read(getClass().getResource("/play.png"))));
                    button.setContentAreaFilled(false);
                    button.setBorderPainted(false);
                    button.setOpaque(false);
                    panel.add(button);
                    panel.setBorder(new CompoundBorder(new LineBorder(Color.RED), new EmptyBorder(10, 10, 10, 10)));

                    button.addActionListener(new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            try {
                                button.setIcon(new ImageIcon(ImageIO.read(getClass().getResource("/record.png"))));
                            } catch (IOException ex) {
                                ex.printStackTrace();
                            }
                        }
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                }

                dialog.pack();
                dialog.setLocationRelativeTo(null);
                dialog.setVisible(true);
            }
        });
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM