很好的问题。
最明显的答案是
WindowUtils.setWindowOpaque(this, false);
这为您提供了您想要的视觉效果,但不幸的是您无法单击窗口!
我尝试的第二件事是重写 Paint() 方法以执行与Window.paint()
当opaque
标志设置为 false。那没有做任何事情。
然后我尝试使用反射。反思性设置Window.opaque
为 true 给出与使用相同的结果WindowUtils
.
最后,我尝试将其添加到enableAeroEffect()
:
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);
}
}
这有效!窗口仍然可以正确响应鼠标事件,但不会绘制背景。这张图有点小问题,但应该可以让你上路。
显然它很脆弱,因为它依赖于反射。如果我是你,我会看看什么Window.setLayersOpaque()
does,并尝试以不依赖反射的方式复制它。
Edit: 在检查时setLayersOpaque
方法,它似乎实际上可以归结为禁用透明组件上的双缓冲。从您的enableAeroEffect()
方法,你就可以了:
//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));
}