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

时间:2016-01-25 23:27:57

标签: java swing jframe jbutton transparency

出于某种原因,当我运行" frame.setBackground(new Color(1.0f,1.0f,1.0f,0.0f));",然后更改我的按钮的图标和重绘(即使使用paintImmediately)我的按钮图标拒绝更改。只是注释掉那条线让它再次起作用,但我有点想要它起作用。

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);

}

我以后跑

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

什么都没发生。

编辑: 我已经阅读了另一个帖子,并检查了他们提供的答案,但我似乎无法找到任何其他来源来验证SWING无法处理alpha值,事实上大多数来源推荐它。另外,根据setOpaque(true/false); Java调用setOpaque似乎意味着使用setOpaque是一个比透明度更复杂的概念。另外,用setOpaque替换setBackground并不起作用,所以我不认为线程应该被关闭,因为另一个线程覆盖了类似的材料。

这是一个不适合我的例子。理论上,这只会留下文本,或者至少只留下按钮占据对话框的部分仍然可见,其余部分不透明。

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);
    }
}

1 个答案:

答案 0 :(得分:1)

要使窗口透明,必须使用setBackground(在窗口类的实例上,如JFrameJDialog) and pass it a transparent color (新颜色(0,0,0,0)) ),这是您在Swing组件上使用基于alpha的颜色的唯一时间。

Swing不知道如何使用基于alpha的颜色绘制组件,它只知道如何处理完全透明或完全不透明的组件,这些组件通过setOpaque控制,例如......

I be blank

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);
            }
        });
    }

}

我可以通过添加

进一步证明这一点
panel.setBorder(new CompoundBorder(new LineBorder(Color.RED), new EmptyBorder(10, 10, 10, 10)));

代码,生成

Still blank

红线实际上是框架的输出(技术上是面板,但为此,它是一样的)

因为按钮/图标有问题......

Play Icon

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);
            }
        });
    }

}