JavaSwing:透明PNG永久捕获原始背景
我有以下代码:JavaSwing:透明PNG永久捕获原始背景,java,swing,Java,Swing,我有以下代码: 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
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();
}
}
import javax.swing.JWindow;
导入javax.swing.ImageIcon;
导入javax.swing.JOptionPane;
导入java.awt.Graphics;
导入java.awt.Image;
导入java.awt.Toolkit;
公共类sutff扩展JWindow
{
//获取将用作启动屏幕图像的透明图像。
Image bi=Toolkit.getDefaultToolkit().getImage(“window.png”);
ImageIcon ii=新的ImageIcon(bi);
公共服务
{
尝试
{
设置大小(ii.getIconWidth(),ii.getIconHeight());
setLocationRelativeTo(空);
show();
//睡眠(10000);
//处置();
//showMessageDialog(null,“此程序将退出!!!”,“”,JOptionPane.INFORMATION\u消息);
}
捕获(异常)
{
异常。printStackTrace();
}
}
//在窗口上绘制透明图像
公共空间涂料(图g)
{
g、 drawImage(bi,0,0,this);
}
公共静态void main(字符串[]args)
{
sutff tss=新的sutff();
}
}
其目的是创建一个半透明的窗口,类似于Windows Aero风格的玻璃。我使用的透明png如下:
问题是因为它是透明的,所以它应该显示窗口后面的东西,对吗?这就是它第一次执行时所做的,除了当它第一次启动时这个“透明窗口”后面的任何窗口外,程序会以某种方式创建一个该窗口的“图像”,并将其永久附加到该窗口。因此,即使我最小化这个“透明窗口”后面的窗口,第一个背景窗口的图像仍然存在
以下是一个屏幕截图:
当我拍摄这个屏幕截图时,我已经最小化了可以在后台看到的命令提示符和IDE,但它仍然保留在窗口的背景中
我做错了什么?不要重写顶级容器的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();
}
}
import javax.swing.*;
导入javax.swing.ImageIcon;
导入javax.swing.JOptionPane;
导入java.awt.*;
导入java.awt.Image;
导入java.awt.Toolkit;
公共类的东西扩展了JWindow
{
//获取将用作启动屏幕图像的透明图像。
Image bi=Toolkit.getDefaultToolkit().getImage(“transparent.png”);
ImageIcon ii=新的ImageIcon(bi);
公共物品
{
尝试
{
后退(新颜色(0,0,0,0));
设置大小(ii.getIconWidth(),ii.getIconHeight());
setLocationRelativeTo(空);
JLabel标签=新JLabel(ii);
添加(标签);
show();
//睡眠(10000);
//处置();
//showMessageDialog(null,“此程序将退出!!!”,“”,JOptionPane.INFORMATION\u消息);
}
捕获(异常)
{
异常。printStackTrace();
}
}
/*
//在窗口上绘制透明图像
公共空间涂料(图g)
{
超级油漆(g);
g、 drawImage(bi,0,0,this);
}
*/
公共静态void main(字符串[]args)
{
Stuff tss=新材料();
}
}
问题是,您的窗口实际上是透明的。Java仍然认为窗口是不透明的,因此不会以这样的方式更新图形,以显示实际背后的内容
在Java中创建透明窗口相对简单,因为Java 1.6.10(我认为)
下面是一个非常简单的示例,使用半透明的绘制效果,可以继续正确绘制掉在窗口下方的内容
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();
}
}
}
使用图像示例更新
屏幕截图显示窗口已移到窗口后面
基本上,您需要做的就是将图像渲染代码放在TestPane的paintComponent
方法中
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();
}
}
}
}
这有助于我了解它的概念部分,但我如何将透明png与此结合?@DemCodeLines,你不明白什么???我提供了使用透明png图像的工作代码。你还需要什么解释?您是否感到困惑,因为我将图像称为“透明”而不是“窗口”?@DemCodeLines与您之前所做的差不多,但以此代码为基础。以图像渲染代码为例,将其放在paintComponent
方法中,简单…-1是使用图像“重塑轮子”的第二个示例。JLabel已按其首选大小显示图像,默认情况下是非不透明的。@camickr如果OP想做的下一件事是向其添加组件,Kleo会踢我的屁股,因为我建议用户在标签上布局组件。没有足够的上下文表明这两种方法都是正确的,尽管我确实同意JLabel
也可以做同样的工作。在这种情况下,我赢不了