У меня проблемы с использованием DWM-функций Windows Vista / 7 в окнах Java. Я хочу, чтобы фон моей рамки был выполнен в стиле Aero. API Windows для этого предоставляется функцией DwmExtendFrameIntoClientArea
в библиотеке dwmapi
. Мне удалось правильно вызвать процедуру через JNA, и она делает то, что должна (вы можете видеть это, например, при изменении размера кадра, перед следующей перерисовкой вы видите правильные аэроэффекты в еще не окрашенной области, см. прикрепленное изображение).
Но где-то (могу ' t выяснить, где) фон закрашивается поверх эффекта Aero, и эффект теряется.
То, что я уже пробовал:
ContentPane
с непрозрачностью false
LayeredPane
и RootPane
на false Frame
вместо JFrame
JFrame
/ ContentPane
на черный / полностью прозрачный setLayersOpaque
и его собственный вариант, см. первый ответ для получения более подробной информации Итак далеко мне не удалось удалить этот фон. Это ограничение AWT / Swing? Как мне удалить этот фон или правильно использовать эффект Aero?
Ваша помощь очень признательна.
Здесь снимок экрана с кадром без какого-либо содержимого с установкой непрозрачности для RootPane, LayeredPane и ContentPane значения false. Я сделал это быстро при изменении размера. Вы видите, что эффект правильно применен к области, которую Java еще не рисовала.
http://i55.tinypic.com/v614qo.png (Как новый пользователь, я не могу опубликовать изображение напрямую .. .)
При дальнейшем исследовании я обнаружил следующее странное поведение. Если размер окна составляет 150x150 или меньше, содержимое отображается прозрачно. Это очень неприятно для обычных оконных компонентов. Если вы рисуете прямо на кадре, переопределив метод paint ()
, все будет отображаться полупрозрачным. Кроме того, система координат кажется немного неправильной, он отображается как нулевая точка JFrame
, установленная на фактическую нулевую точку окна. Таким образом, Swing пытается закрасить области, где на самом деле находится граница окна, которая тогда, конечно, не видна.
Смотрите этот снимок экрана: http://d-gfx.kognetwork.ch/java_aero_bug.png
Это код, который я использую.
Требуется jna.jar
и platform.jar
. Доступно на домашней странице JNA.
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);
}
}