una poner imagen form fondo contenedor como colocar cargar java swing jframe jna dwm

form - poner imagen en jlabel java



Deshabilitar el dibujo de fondo en JFrame para mostrar correctamente los efectos Aero(DWM) (1)

Gran pregunta

La respuesta más obvia sería

WindowUtils.setWindowOpaque(this, false);

¡Eso le da los efectos visuales que desea pero desafortunadamente le impide hacer clic en la Ventana!

Lo segundo que probé fue anular el método paint () para realizar las mismas acciones que Window.paint() cuando el indicador opaque se establece en falso. Eso no hizo nada.

Luego traté de usar Reflection. La configuración reflexiva de Window.opaque en true dio los mismos resultados que con WindowUtils .

Finalmente, intenté agregar esto para 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); } }

Esto funcionó! La ventana todavía responde correctamente a los eventos del mouse, pero el fondo no se dibuja. El dibujo es un poco impreciso, pero debería ponerlo en su camino.

Obviamente es frágil ya que depende de Reflection. Si yo fuera tú, Window.setLayersOpaque() un vistazo a lo que hace Window.setLayersOpaque() e intentaré replicarlo de una manera que no dependa de Reflection.

Editar : Al inspeccionar el método setLayersOpaque , realmente parece reducirse a la desactivación del doble almacenamiento en los componentes transparentes. Llame a este método desde su método enableAeroEffect() y enableAeroEffect() en camino:

//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)); }

Tengo problemas para usar la funcionalidad DWM de Windows Vista / 7 en las ventanas de Java. Quiero hacer que el fondo de mi marco use el estilo Aero. La API de Windows para hacerlo es proporcionada por la función DwmExtendFrameIntoClientArea en la biblioteca dwmapi . He logrado llamar el procedimiento correctamente a través de JNA, y hace lo que se supone que debe hacer (Puedes ver que, por ejemplo, al redimensionar el fotograma, antes del siguiente repintado puedes ver los efectos aerodinámicos adecuados en el área que aún no está pintada, ver la imagen adjunta).

Pero en algún lugar (no puedo averiguar dónde) un fondo está pintado sobre el efecto Aero y el efecto se pierde.

Lo que ya he intentado:

  • Usar un ContentPane personalizado con la opacidad establecida en false
  • Establecer la opacidad del LayeredPane y el RootPane en falso
  • Usar un Frame lugar de un Frame JFrame
  • Establezca el color de fondo de JFrame / ContentPane en negro / completamente transparente
  • Use setLayersOpaque y una variante personalizada del mismo; consulte la primera respuesta para obtener más detalles.

Hasta ahora no he podido eliminar ese fondo. ¿Es una limitación de AWT / Swing? ¿Cómo puedo eliminar ese fondo o usar el efecto Aero correctamente?

Tu ayuda es muy apreciada.

Captura de pantalla

Aquí una captura de pantalla de un marco sin ningún contenido, estableciendo la opacidad de RootPane, LayeredPane y ContentPane en false. Lo hice rápidamente mientras cambio el tamaño. Verá que el efecto se aplica correctamente al área que Java aún no pintó.

http://i55.tinypic.com/v614qo.png (Como nuevo usuario, no puedo publicar la imagen directamente ...)

Comportamiento raro

Tras una investigación más profunda encontré el siguiente comportamiento extraño. Si el tamaño de la ventana es 150x150 o inferior, los contenidos se muestran de forma transparente. Esto es muy complicado para los componentes de ventana normales. Si pintas directamente en el cuadro anulando el método paint() todo se dibuja semitransparente. Además, el sistema de coordenadas parece estar un poco apagado, ya que el punto cero del JFrame se establece en el punto cero real de la ventana. Por lo tanto, Swing trata de pintar en las áreas donde realmente se encuentra el borde de la ventana, que por supuesto no es visible.

Vea esta captura de pantalla: http://d-gfx.kognetwork.ch/java_aero_bug.png

Código de ejemplo

Este es el código que uso.

Requiere jna.jar y platform.jar . Disponible desde la página de inicio de 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); } }