Java的透明窗口(Java transparent window)

2019-06-26 19:40发布

我想创建跟随鼠标的圆圈形的窗口,并通过点击到下面的窗口。

我是用Python和Qt的做这个(见Python的重叠窗口 ),但后来我切换到Java和Swing。 但是我不能使窗口透明。 我试过这种方法 ,但它不工作,但我认为我的系统支持的透明度,因为如果我开始截屏-O-Matic的 (这是在Java中),矩形实际上是透明的。

我如何才能做到这样的事情? (我在Linux上KDE4)

Answer 1:

为什么Java教程如何创建透明和不规则窗口无法正常工作? 您是否正在使用最新版本的Java 6或Java 7的? 在Java的杂志五月/六月的问题 ,有需要对Java 7中你可能会需要注册为Java杂志才能阅读其形状和透明窗口的教程。 看看你是否能得到这个系统上运行:

import java.awt.*; //Graphics2D, LinearGradientPaint, Point, Window, Window.Type;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

/**
 * From JavaMagazine May/June 2012
 * @author josh
 */
public class ShapedAboutWindowDemo {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        //switch to the right thread
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("About box");
                //turn of window decorations
                frame.setUndecorated(true);
                //turn off the background
                frame.setBackground(new Color(0,0,0,0));
                frame.setContentPane(new AboutComponent());
                frame.pack();
                //size the window
                frame.setSize(500, 200);
                frame.setVisible(true);
                //center on screen
                frame.setLocationRelativeTo(null);
            }
        }
        );
    }

    private static class AboutComponent extends JComponent {
        public void paintComponent(Graphics graphics) {
            Graphics2D g = (Graphics2D) graphics;

            //create a translucent gradient
            Color[] colors = new Color[]{
                           new Color(0,0,0,0)
                            ,new Color(0.3f,0.3f,0.3f,1f)
                            ,new Color(0.3f,0.3f,0.3f,1f)
                            ,new Color(0,0,0,0)};
            float[] stops = new float[]{0,0.2f,0.8f,1f};
            LinearGradientPaint paint = new LinearGradientPaint(
                                        new Point(0,0), new Point(500,0),
                                        stops,colors);
            //fill a rect then paint with text
            g.setPaint(paint);
            g.fillRect(0, 0, 500, 200);
            g.setPaint(Color.WHITE);
            g.drawString("My Killer App", 200, 100);
        }
    }
}


Answer 2:

如果您使用的是Java 6,您需要使用私人API AWTUtilities的。 退房的Java SE 6 Update 10的API的更多详细信息

这是一个有点快劈,但它跨越有想法

public class TransparentWindow {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {

                MyFrame frame = new MyFrame();
                frame.setUndecorated(true);

                String version = System.getProperty("java.version");
                if (version.startsWith("1.7")) {


                    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
                    GraphicsDevice graphicsDevice = ge.getDefaultScreenDevice();

                    System.out.println("Transparent from under Java 7");
                    /* This won't run under Java 6, uncomment if you are using Java 7
                    System.out.println("isPerPixelAlphaTranslucent = " + graphicsDevice.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT));
                    System.out.println("isPerPixelAlphaTransparent = " + graphicsDevice.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT));
                    System.out.println("isPerPixelAlphaTranslucent = " + graphicsDevice.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.TRANSLUCENT));
                    */
                    frame.setBackground(new Color(0, 0, 0, 0));

                } else if (version.startsWith("1.6")) {

                    System.out.println("Transparent from under Java 6");
                    System.out.println("isPerPixelAlphaSupported = " + supportsPerAlphaPixel());
                    setOpaque(frame, false);

                }

                frame.setSize(400, 400);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

            }
        });

    }

    public static class MyFrame extends JFrame {

        public MyFrame() throws HeadlessException {

            setContentPane(new MyContentPane());
            setDefaultCloseOperation(EXIT_ON_CLOSE);

            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {

                    if (e.getClickCount() == 2) {

                        dispose();

                    }

                }
            });

        }
    }

    public static class MyContentPane extends JPanel {

        public MyContentPane() {

            setLayout(new GridBagLayout());
            add(new JLabel("Hello, I'm a transparent frame under Java " + System.getProperty("java.version")));

            setOpaque(false);

        }

        @Override
        protected void paintComponent(Graphics g) {

            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setColor(Color.BLUE);

            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
            g2d.fillRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 20, 20);

        }
    }

    public static boolean supportsPerAlphaPixel() {

        boolean support = false;

        try {

            Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
            support = true;

        } catch (Exception exp) {
        }

        return support;

    }

    public static void setOpaque(Window window, boolean opaque) {

        try {

            Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
            if (awtUtilsClass != null) {

                Method method = awtUtilsClass.getMethod("setWindowOpaque", Window.class, boolean.class);
                method.invoke(null, window, opaque);
//                com.sun.awt.AWTUtilities.setWindowOpaque(this, opaque);
//                ((JComponent) window.getContentPane()).setOpaque(opaque);

            }

        } catch (Exception exp) {
        }

    }

    public static void setOpacity(Window window, float opacity) {

        try {

            Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
            if (awtUtilsClass != null) {

                Method method = awtUtilsClass.getMethod("setWindowOpacity", Window.class, float.class);
                method.invoke(null, window, opacity);

            }

        } catch (Exception exp) {

            exp.printStackTrace();

        }

    }

    public static float getOpacity(Window window) {

        float opacity = 1f;
        try {

            Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
            if (awtUtilsClass != null) {

                Method method = awtUtilsClass.getMethod("getWindowOpacity", Window.class);
                Object value = method.invoke(null, window);
                if (value != null && value instanceof Float) {

                    opacity = ((Float) value).floatValue();

                }

            }

        } catch (Exception exp) {

            exp.printStackTrace();

        }


        return opacity;

    }
}

在Windows 7中产生

在Java 6中

在Java 7中



Answer 3:

我想这会的工作,我已经尝试过it..to做一个JFrame或窗口透明的,你需要去除装饰Undecorated(true)第一帧。 下面是示例代码:

import javax.swing.*;
import com.sun.awt.AWTUtilities;
import java.awt.Color;   

    class transFrame {
      private JFrame f=new JFrame();
      private JLabel msg=new JLabel("Hello I'm a Transparent Window");

     transFrame() {
       f.setBounds(400,150,500,500);
       f.setLayout(null);
       f.setUndecorated(true);     // Undecorates the Window
       f.setBackground(new Color(0,0,0,25));  // fourth index decides the opacity
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       msg.setBounds(150,250,300,25);
       f.add(msg);
       f.setVisible(true);
      }

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

     }

唯一的问题是,你需要添加自己的代码进行密切和使用按钮最小化。



Answer 4:

如果你想这样做你自己,而无需使用外部的lib,你可以开始执行一个线程:

  • 设置透明窗口不可见
  • 使桌面的屏幕截图
  • 把这个截图作为你的窗口的背景图片

或者你可以使用JavaFX的



文章来源: Java transparent window