Отличный вопрос.
Самый очевидный ответ будет
WindowUtils.setWindowOpaque(this, false);
Это дает вам визуальные эффекты, которые вы хотите, но, к сожалению, лишает вас возможности нажать на окно!
Во-вторых, я попытался переопределить метод paint (), чтобы выполнить те же действия, что и Window.paint()
, когда для флага opaque
установлено значение false. Это ничего не сделало.
Тогда я попытался использовать Reflection. Рефлексивная установка 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()
делает , и попытался бы воспроизвести это так, чтобы это не зависело от Reflection.
Редактировать : При проверке метода 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));
}