DwmExtendFrameIntoClientAreadwmapiContentPanefalseLayeredPaneRootPaneFrameJFrameJFrameContentPanesetLayersOpaquepaint()JFramejna.jar
import com.sun.jna.Function;
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinNT.HRESULT;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;

public class AeroFrame extends JFrame {

    public AeroFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLabel label = new JLabel("Testlabel");
        label.setOpaque(false);

        add(label);

        pack();

        enableAeroEffect();
    }

    private void enableAeroEffect() {
        NativeLibrary dwmapi = NativeLibrary.getInstance("dwmapi");
        HWND aeroFrameHWND = new HWND(Native.getWindowPointer(this));
        MARGINS margins = new MARGINS();
        margins.cxLeftWidth = -1;
        margins.cxRightWidth = -1;
        margins.cyBottomHeight = -1;
        margins.cyTopHeight = -1;
        //DwmExtendFrameIntoClientArea(HWND hWnd, MARGINS *pMarInset)
        //http://msdn.microsoft.com/en-us/library/aa969512%28v=VS.85%29.aspx
        Function extendFrameIntoClientArea = dwmapi.getFunction("DwmExtendFrameIntoClientArea");
        HRESULT result = (HRESULT) extendFrameIntoClientArea.invoke(HRESULT.class,
                new Object[] { aeroFrameHWND, margins});
        if(result.intValue()!=0)
            System.err.println("Call to DwmExtendFrameIntoClientArea failed.");
    }

    /**
     * http://msdn.microsoft.com/en-us/library/bb773244%28v=VS.85%29.aspx
     */
    public class MARGINS extends Structure implements Structure.ByReference {
            public int cxLeftWidth;
            public int cxRightWidth;
            public int cyTopHeight;
            public int cyBottomHeight;
    }

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            JFrame.setDefaultLookAndFeelDecorated(true);

        } catch (Exception e) {
            e.printStackTrace();
        }
        new AeroFrame().setVisible(true);
    }

}

最佳答案:

好问题。
最明显的答案是

WindowUtils.setWindowOpaque(this, false);

这给了你想要的视觉效果,但不幸的是,你无法点击窗口!
我尝试的第二件事是重写paint()方法以执行与
Window.paint()
标志设置为false时相同的操作。什么都没做。
然后我试着用倒影。反射设置为“真”的结果与使用“真”的结果相同。
最后,我尝试将此添加到
Method m = null;
try {
    m = Window.class.getDeclaredMethod("setLayersOpaque", Component.class, Boolean.TYPE);
    m.setAccessible(true);
    m.invoke(null, this, false);
} catch ( Exception e ) {
    //TODO: handle errors correctly
} finally {
    if ( m != null ) {
        m.setAccessible(false);
    }
}

这奏效了!窗口仍然对鼠标事件做出正确响应,但未绘制背景。这幅画有点浮华,但应该让你上路。
显然它很脆弱,因为它依赖于反射。如果我是你,我会看一下
opaque
的作用,并尝试以一种不依赖反射的方式复制它。
编辑:在检查
Window.opaque
方法时,它实际上似乎归结为禁用透明组件上的双缓冲。从您的
WindowUtils
方法调用此方法,您就可以开始了:
//original source: Sun, java/awt/Window.java, setLayersOpaque(Component, boolean)
private static void setLayersTransparent(JFrame frame) {
    JRootPane root = frame.getRootPane();
    root.setOpaque(false);
    root.setDoubleBuffered(false);

    Container c = root.getContentPane();
    if (c instanceof JComponent) {
        JComponent content = (JComponent) c;
        content.setOpaque(false);
        content.setDoubleBuffered(false);
    }
    frame.setBackground(new Color(0, 0, 0, 0));
}