0

我有以下代码:

import javax.swing.JWindow;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;

public class sutff extends JWindow
{
    //Get transparent image that will be use as splash screen image.
    Image bi=Toolkit.getDefaultToolkit().getImage("window.png");
    ImageIcon ii=new ImageIcon(bi);
    public sutff()
    {
        try
        {
            setSize(ii.getIconWidth(),ii.getIconHeight());
            setLocationRelativeTo(null);
            show();
            //Thread.sleep(10000);
            //dispose();
            //JOptionPane.showMessageDialog(null,"This program will exit !!!","<>",JOptionPane.INFORMATION_MESSAGE);
        }
        catch(Exception exception)
        {
            exception.printStackTrace();
        }
    }
    //Paint transparent image onto JWindow
    public void paint(Graphics g)
    {
        g.drawImage(bi,0,0,this);
    }
    public static void main(String[]args)
    {
        sutff tss=new sutff();
    }
}

目的是创建一个半透明的窗口,类似于 Windows Aero 风格的玻璃。我正在使用以下透明 png:http: //i.imgur.com/5UNGbsr.png

问题是由于它是透明的,它应该显示窗户后面的东西,对吧?这就是它第一次执行时所做的事情,除了第一次启动时这个“透明窗口”后面的任何窗口,程序都会以某种方式创建一个“图像”并将其永久附加到窗口中。因此,即使我将这个“透明窗口”后面的窗口最小化,第一个背景窗口的图像仍然存在。

这是一个屏幕截图:

在此处输入图像描述

当我拍摄这个屏幕截图时,我已经最小化了可以在后台看到的命令提示符和 IDE,但它仍然保留在窗口的背景中。

我究竟做错了什么?

4

2 回答 2

4

不要覆盖顶级容器的paint() 方法,尤其是当您不调用super.paint() 时。这将导致绘画问题。如果您确实需要进行自定义绘画,那么您应该覆盖 JPanel(或 JComponent)的 paintComponent() 方法,然后将面板添加到窗口/框架。阅读自定义绘画的 Swing 教程。这个建议每天都会给出,我不知道为什么人们仍然试图覆盖paint()???

然而,这只是你的问题之一。更好的解决方案是将图像添加到 JLabel,然后将标签添加到窗口。您还需要使窗口背景透明:

import javax.swing.*;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import java.awt.*;
import java.awt.Image;
import java.awt.Toolkit;

public class Stuff extends JWindow
{
    //Get transparent image that will be use as splash screen image.
    Image bi=Toolkit.getDefaultToolkit().getImage("transparent.png");
    ImageIcon ii=new ImageIcon(bi);
    public Stuff()
    {
        try
        {
            setBackground( new Color(0, 0, 0, 0) );
            setSize(ii.getIconWidth(),ii.getIconHeight());
            setLocationRelativeTo(null);
            JLabel label = new JLabel(ii);
            add(label);
            show();
            //Thread.sleep(10000);
            //dispose();
            //JOptionPane.showMessageDialog(null,"This program will exit !!!","<>",JOptionPane.INFORMATION_MESSAGE);
        }
        catch(Exception exception)
        {
            exception.printStackTrace();
        }
    }

/*
    //Paint transparent image onto JWindow
    public void paint(Graphics g)
    {
        super.paint(g);
        g.drawImage(bi,0,0,this);
    }
*/
    public static void main(String[]args)
    {
        Stuff tss=new Stuff();
    }
}
于 2013-04-13T00:14:57.463 回答
3

问题是,你的窗口实际上是透明的。Java 仍然认为窗口不透明,因此不会更新图形以显示实际背后的内容。

自 Java 1.6.10 以来,在 Java 中创建透明窗口相对简单(我认为)

下面是一个非常简单的示例,使用半透明的绘制效果,这将允许任何落在窗口下方的东西继续正确绘制。

import com.sun.awt.AWTUtilities;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TransaprentBlur {

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

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

                JFrame frame = new JFrame("Testing");
                frame.setUndecorated(true);
                frame.setBackground(new Color(0, 0, 0, 0));
//                Java 6...
//                AWTUtilities.setWindowOpaque(frame, true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.setSize(400, 400);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setOpaque(false);

            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getClickCount() == 2) {
                        System.exit(0);
                    }
                }
            });
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Shape shape = new RoundRectangle2D.Float(0, 0, getWidth() - 1, getHeight() - 1, 20, 20);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(new Color(225, 225, 225, 128));
            g2d.fill(shape);
            g2d.setColor(Color.GRAY);
            g2d.draw(shape);
            g2d.dispose();
        }

    }

}

使用图像示例更新

屏幕截图显示窗户被移到窗户后面......

在此处输入图像描述在此处输入图像描述

基本上,您需要做的就是将图像渲染代码paintComponent放在TestPane

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TransaprentBlur {

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

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

                JFrame frame = new JFrame("Testing");
                frame.setUndecorated(true);
                frame.setBackground(new Color(0, 0, 0, 0));
//                Java 6...
//                AWTUtilities.setWindowOpaque(frame, true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.setSize(400, 400);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage image;

        public TestPane() {

            try {
                image = ImageIO.read(getClass().getResource("/5UNGbsr.png"));
            } catch (IOException ex) {
            }
            setOpaque(false);

            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getClickCount() == 2) {
                        System.exit(0);
                    }
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(), image.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (image != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                int x = (getWidth() - image.getWidth()) / 2;
                int y = (getHeight() - image.getHeight()) / 2;
                g2d.drawImage(image, x, y, this);
                g2d.dispose();
            }
        }

    }

}
于 2013-04-13T02:56:02.657 回答