如何拥有透明模糊背景的 JFrame

How to have a JFrame with transparent Blurred background

我只是想知道是否有办法使 JFrame 的背景变得模糊。类似于 iOS 效果。 Image

在Java有可能吗? Windows 和 Mac.

我需要它

我一直在断断续续地研究这个,但从来没有真正得到满意的结果。为什么?因为为了让它工作,你需要使 window 透明(实际上是半透明的),但是当使用原生外观装饰时,window 必须不被装饰才能工作......

nb:这利用了 TeamDev JNI Library and associated WinPack Library - 因为当我开始使用这种类型的东西时,JNA 还处于起步阶段

import com.jniwrapper.Function;
import com.jniwrapper.Library;
import com.jniwrapper.Parameter;
import com.jniwrapper.Pointer;
import com.jniwrapper.UInt32;
import com.jniwrapper.win32.ui.Wnd;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Window;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class TestDWM {

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

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

                final JFrame frame = new JFrame();
                frame.setUndecorated(true);
                frame.setBackground(new Color(0, 0, 0, 0));

                TranslucentPane panel = new TranslucentPane();
                frame.setContentPane(panel);

                panel.setBorder(new EmptyBorder(40, 40, 40, 40));

                frame.setLayout(new GridBagLayout());
                JLabel label = new JLabel("I'm a banana");
                label.setFont(label.getFont().deriveFont(Font.BOLD, 48f));
                frame.add(label);

                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setAlwaysOnTop(true);
                frame.setVisible(true);

                setBlurBehind(frame);
            }
        });
    }

    public class TranslucentPane extends JPanel {

        public TranslucentPane() {
            setOpaque(false);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Color color = getBackground();
            color = new Color(color.getRed(), color.getGreen(), color.getBlue(), 32);
            g.setColor(color);
            g.fillRect(0, 0, getWidth(), getHeight());
        }

    }

    public static void setBlurBehind(Window window) {

        Wnd wnd = new Wnd(window);
        Library libDWMAPI = new Library("Dwmapi");
        Function fEnableBlurBehindWindow = libDWMAPI.getFunction("DwmEnableBlurBehindWindow");
        DWMBlurBehind behind = new DWMBlurBehind();

        System.out.println("wnd = " + wnd);

        UInt32 dwResult = new UInt32(0);
        long hResult = fEnableBlurBehindWindow.invoke(
                        dwResult,
                        new Parameter[]{
                            wnd,
                            new Pointer(behind)
                        });

        System.out.println("hResult = " + hResult);
        System.out.println("dwResult = " + dwResult.getValue());

    }

}

还有 DWMBlurBehind class

import com.jniwrapper.Int;
import com.jniwrapper.Parameter;
import com.jniwrapper.Pointer;
import com.jniwrapper.Structure;
import com.jniwrapper.UInt32;
import windows.WinDef;

public class DWMBlurBehind extends Structure {

    public static final int DWM_BB_ENABLED = 0x1;
    public static final int DWM_BB_BLURREGION = 0x2;
    public static final int DWM_BB_TRANSITIONONMAXIMIZED = 0x4;

    private UInt32 dwFlags;
    private Int enabled;
    private Pointer.Void region;
    private Int transitionOnMazimized;

    public DWMBlurBehind() {

        dwFlags = new UInt32(DWM_BB_ENABLED);
        enabled = new Int(WinDef.TRUE);
        transitionOnMazimized = new Int(WinDef.TRUE);
        region = new Pointer.Void();
        init(new Parameter[]
        {
            dwFlags,
            enabled,
            region,
            transitionOnMazimized
        });
    }

    public long getFlags() {
        return dwFlags.getValue();
    }

}

现在,说了这么多,如果您不关心 UI 使用本机外观,您可以创建一个装饰框架(使用外观装饰)作为 demonstrated here