繁体   English   中英

如何使 JFrame contentPane 透明但 JFrame 可见?

[英]How to make the JFrame contentPane transparent but the JFrame visible?

我想知道如何使 JFrame 的 contentPane 透明但 JFrame 可见。 我看到了很多页面,但都展示了如何使 JFrame 边框可见但 contentPane 可见。

我尝试使用setOpacity()但这需要 JFrame 是undecorated

有什么方法可以实现吗?

您可以对 JFrame 内部的每个元素使用 setVisible(false) 方法。 您在 intialize() 方法中使用它。 一旦您希望显示它们(例如在单击某个按钮后),您将使用相同的方法 setVisible(true)。

Swing 并非设计用于使用透明背景进行绘制。 您不能创建透明的 contentPane。 但是,您可以伪造透明背景。

这是一个显示假透明背景的屏幕截图。 我将图像裁剪并缩小了 50% 以使其显示在此答案中。

在此处输入图像描述

那么,我是怎么做到的呢?

我拍摄了背景快照并在JPanel上绘制了背景。

仅当您在显示JFrame不更改背景时,这才有效。 如果您通过打开或关闭任何其他应用程序来更改背景,则此伪造将不起作用

您可以移动JFrame 不要将 JFrame 靠近屏幕边缘,否则会破坏错觉。

JFrame进行图标化和去图标化是可行的,但这种错觉变得很明显。

您可以调整、最大化和恢复JFrame

它需要大量代码才能使这个假货正常工作。

这是完整的可运行代码。 我将所有附加类都设为内部类,因此我可以将此代码作为一个块发布。

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TransparentJPanelView implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new TransparentJPanelView());
    }
    
    private DrawingPanel drawingPanel;
    
    private JFrame frame;
    
    private TransparentJPanelModel model;
    
    public TransparentJPanelView() {
        this.model = new TransparentJPanelModel();
        this.drawingPanel = new DrawingPanel(model);
    }

    @Override
    public void run() {
        this.frame = new JFrame("Fake Transparent JPanel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.addComponentListener(new FrameComponentListener(this, model));
        FrameListener listener = new FrameListener(this, model);
        frame.addWindowListener(listener);
        frame.addWindowFocusListener(listener);
        frame.addWindowStateListener(listener);

        frame.add(drawingPanel, BorderLayout.CENTER);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    public void repaint() {
        drawingPanel.repaint();
    }
    
    public JFrame getFrame() {
        return frame;
    }

    public class DrawingPanel extends JPanel {

        private static final long serialVersionUID = 1L;
        
        private TransparentJPanelModel model;
        
        public DrawingPanel(TransparentJPanelModel model) {
            this.model = model;
            this.setLayout(new FlowLayout());
            this.setPreferredSize(new Dimension(600, 300));
            
            JButton button = new JButton("Click me");
            this.add(button);
        }
        
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            
            Point point = new Point(this.getLocation()); 
            SwingUtilities.convertPointToScreen(point, this); 
            
            Image image = model.getSubImage(point.x, point.y, getWidth(), getHeight());
            g.drawImage(image, 0, 0, this);
        }
        
    }
    
    public class FrameComponentListener extends ComponentAdapter {
        
        private final TransparentJPanelView view;
        
        private final TransparentJPanelModel model;
        
        public FrameComponentListener(TransparentJPanelView view, 
                TransparentJPanelModel model) {
            this.view = view;
            this.model = model;
        }

        @Override
        public void componentResized(ComponentEvent event) {
            view.repaint();
        }

        @Override
        public void componentMoved(ComponentEvent event) {
            view.repaint();
        }

    }
    
    public class FrameListener extends WindowAdapter { 

        private final TransparentJPanelView view;
        
        private final TransparentJPanelModel model;
        
        public FrameListener(TransparentJPanelView view, 
                TransparentJPanelModel model) {
            this.view = view;
            this.model = model;
        }
        
        @Override
        public void windowDeiconified(WindowEvent event) {
            model.setBackground();
            view.repaint();
        }
        
    }
    
    public class TransparentJPanelModel {
        
        private BufferedImage background;
        
        private final Rectangle screenRect;
        
        private final Robot robot;
        
        public TransparentJPanelModel() {
            this.robot = createRobot();
            this.screenRect = new Rectangle(
                    Toolkit.getDefaultToolkit().getScreenSize());
            setBackground();
        }
        
        private Robot createRobot() {
            Robot robot = null;
            try {
                robot = new Robot();
            } catch (AWTException e) {
                e.printStackTrace();
            }
            return robot;
        }

        public void setBackground() {
            this.background = robot.createScreenCapture(screenRect);
        }
        
        public Image getSubImage(int x, int y, int width, int height) {
            if (x < 0) {
                x = 0;
                width = Math.min(width, screenRect.width);
            }
            
            if (y < 0) {
                y = 0;
                height = Math.min(height, screenRect.height);
            }
            
            if (x + width > screenRect.width) {
                width = screenRect.width - x;
            }
            
            if (y + height > screenRect.height) {
                height = screenRect.height - y;
            }
            
            return background.getSubimage(x, y, width, height);
        }
        
    }
    
}

暂无
暂无

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

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