簡體   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