透明 JDesktopPane [英] Transparent JDesktopPane

查看:29
本文介绍了透明 JDesktopPane的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将 JDesktopPane 设置为透明,并允许我点击下面的内容(例如桌面图标等).内部框架应该保持不透明,并且能够像当前一样在屏幕周围重新定位.有什么想法吗?

I would like to set the JDesktopPane to transparent and allow me to click through to what is underneath (e.g.. Desktop icons etc). The internal frame should be left opaque and able to be repositioned around the screen as it currently does. Any ideas?

    package test1;

    import java.awt.BorderLayout;
    import java.awt.Color;
    import javax.swing.JDesktopPane;
    import javax.swing.JFrame;
    import javax.swing.JInternalFrame;
    import javax.swing.JLabel;


    public class Test1 {

    public static void main(String[] args) {

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setUndecorated(true);


    JDesktopPane desktop = new JDesktopPane();
    JInternalFrame internalFrame = new JInternalFrame("Title", false, true, false, true);
    desktop.setBackground(Color.RED);  
    //desktop.setBackground(new Color(1.0f,1.0f,1.0f,0.0f));
    desktop.add(internalFrame);
    internalFrame.setBounds(25, 25, 200, 100);
    internalFrame.setVisible(true);
    frame.add(desktop, BorderLayout.CENTER);
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 
    frame.setVisible(true);

    }

}

推荐答案

Part #1 Translucent JInternalFrame

创建半透明组件比将背景颜色设置为基于 alpha 的值要复杂得多.

Part #1 Translucent JInternalFrame

Creating a translucent component is more involved then just setting the background color to an alpha based value.

Swing 只知道如何绘制不透明或完全透明的组件,API 也进行了优化,如果它正在更新一个不透明的组件,它不会更新组件后面的父级区域.使用基于 alpha 的颜色会产生各种令人讨厌的油漆伪影

Swing only knows how to paint either opaque or fully transparent components, the API is also optimised in such away that if it's updating an opaque component, it won't update the area of the parent behind the component. Using an alpha based color will generate all kinds of nasty paint artifacts

相反,您需要伪造"它.这涉及将组件设置为完全覆盖组件 paint 方法并使用 AlphaComposite 生成半透明效果(通常我会使用 paintComponent> 方法,但您必须记住,这不会影响子组件)

Instead, you need to "fake" it. This involves setting the component to be fully overriding the components paint method and using a AlphaComposite to generate the translucent effect (normally I'd use the paintComponent method, but you have to remember that that would leave the child components unaffected)

import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Main {

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

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

                    JDesktopPane dp = new BackgroundDesktopPane();

                    BufferedImage img = ImageIO.read(new File("C:\\Users\\shane\\Dropbox\\Ponies\\SmallPony.png"));

                    TransparentInternalFrame iframe = new TransparentInternalFrame("Banana", true, true, true, true);
                    iframe.setLocation(10, 10);
                    iframe.add(new JLabel(new ImageIcon(img)));
                    iframe.pack();
                    iframe.setVisible(true);

                    dp.add(iframe);


                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(dp);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class TransparentInternalFrame extends JInternalFrame {

        public TransparentInternalFrame() {
            super();
        }

        public TransparentInternalFrame(String title) {
            super(title);
        }

        public TransparentInternalFrame(String title, boolean resizable) {
            super(title, resizable);
        }

        public TransparentInternalFrame(String title, boolean resizable, boolean closable) {
            super(title, resizable, closable);
        }

        public TransparentInternalFrame(String title, boolean resizable, boolean closable, boolean maximizable) {
            super(title, resizable, closable, maximizable);
        }

        public TransparentInternalFrame(String title, boolean resizable, boolean closable, boolean maximizable, boolean iconifiable) {
            super(title, resizable, closable, maximizable, iconifiable);
        }

        @Override
        public void paint(Graphics g) {
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setComposite(AlphaComposite.SrcOver.derive(0.25f));
            super.paint(g2d);
            g2d.dispose();
        }

    }

    public class BackgroundDesktopPane extends JDesktopPane {

        private BufferedImage background;

        public BackgroundDesktopPane() throws IOException {
            background = ImageIO.read(new File("C:\\Users\\shane\\Dropbox\\Ponies\\800px-Rainbow_Dash_flying_past_1_S2E16.png"));
        }

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

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



    }

}

第 2 部分点击...

提供点击组件的能力要困难得多,如果添加支持鼠标事件的组件,就会变得困难得多.以下将允许鼠标事件穿过"组件(除了框架板),但响应鼠标事件的内部框架中的任何组件都将阻止其工作.

Part #2 Click through...

Providing the ability to click through the components is a lot more difficult and becomes a lot more difficult if you add components which support mouse events. The following will allow mouse events to "fall through" the component (expect the frame boards), but any component in the internal frame which responds to mouse events will stop this from working.

public class TransparentInternalFrame extends JInternalFrame {

    public TransparentInternalFrame() {
        super();
        setOpaque(false);
        init();
    }

    public TransparentInternalFrame(String title) {
        super(title);
        setOpaque(false);
        init();
    }

    public TransparentInternalFrame(String title, boolean resizable) {
        super(title, resizable);
        setOpaque(false);
        init();
    }

    public TransparentInternalFrame(String title, boolean resizable, boolean closable) {
        super(title, resizable, closable);
        setOpaque(false);
        init();
    }

    public TransparentInternalFrame(String title, boolean resizable, boolean closable, boolean maximizable) {
        super(title, resizable, closable, maximizable);
        setOpaque(false);
        init();
    }

    public TransparentInternalFrame(String title, boolean resizable, boolean closable, boolean maximizable, boolean iconifiable) {
        super(title, resizable, closable, maximizable, iconifiable);
        setOpaque(false);
        init();
    }

    protected void init() {
        MouseAdapter proxy = new MouseAdapter() {

            protected void dispatchEventToParent(MouseEvent e) {
                Container parent = getParent();
                if (parent != null) {
                    e = SwingUtilities.convertMouseEvent(e.getComponent(), e, parent);
                    parent.dispatchEvent(e);
                }
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                dispatchEventToParent(e);
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                dispatchEventToParent(e);
            }

            @Override
            public void mouseWheelMoved(MouseWheelEvent e) {
                dispatchEventToParent(e);
            }

            @Override
            public void mouseExited(MouseEvent e) {
                dispatchEventToParent(e);
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                dispatchEventToParent(e);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                dispatchEventToParent(e);
            }

            @Override
            public void mousePressed(MouseEvent e) {
                dispatchEventToParent(e);
            }

            @Override
            public void mouseClicked(MouseEvent e) {
                dispatchEventToParent(e);
            }

        };

        addMouseListener(proxy);
        addMouseMotionListener(proxy);
        addMouseWheelListener(proxy);
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setComposite(AlphaComposite.SrcOver.derive(0.25f));
        super.paint(g2d);
        g2d.dispose();
    }

}

public class BackgroundDesktopPane extends JDesktopPane {

    private BufferedImage background;
    private List<Point> points;

    public BackgroundDesktopPane() throws IOException {
        points = new ArrayList<>(25);
        background = ImageIO.read(new File("C:\\Users\\shane\\Dropbox\\Ponies\\800px-Rainbow_Dash_flying_past_1_S2E16.png"));
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                points.add(e.getPoint());
                repaint();
            }

        });
    }

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

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

        g2d.setColor(Color.RED);
        for (Point p : points) {
            g2d.fillOval(p.x - 5, p.y - 5, 10, 10);
        }
        g2d.dispose();
    }

}

这篇关于透明 JDesktopPane的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆