Java ウィンドウで Windows Vista/7 の DWM 機能を使用すると問題が発生します。フレームの背景に Aero スタイルを使用したいと考えています。DwmExtendFrameIntoClientArea
そのための Windows APIは、dwmapi
ライブラリ内の関数によって提供されます。私は JNA を介して適切にプロシージャを呼び出すことができました。それは本来の動作を実行します (たとえば、フレームのサイズを変更すると、次の再ペイントの前に、まだペイントされていない領域に適切なエアロ エフェクトが表示されることがわかります。添付画像をご覧ください)。
しかし、どこか (どこかわかりません) で、Aero 効果の上に背景がペイントされ、効果が失われます。
私がすでに試したこと:
ContentPane
不透明度を設定してカスタムを使用するfalse
LayeredPane
との不透明度RootPane
を falseに設定する- a の
Frame
代わりに aを使用する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);
}
}