java swing java-8 jframe transparency

Establecer la opacidad de un JFrame decorado en Java 8



swing java-8 (2)

Me gustaría saber cómo obtener un JFrame transparente en la última versión de Java.

Actualmente, solo puedes usar

<JFrame>.setOpacity();

si el marco no está decorado .

No me sirve para un fotograma no decorado, por lo que me gustaría saber cómo 0.5f esta restricción y establecer la opacidad del fotograma en 0.5f sin perder la barra de título, cambiar el tamaño de las opciones, etc.

He leído los documentos aquí: http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html . El código solo funciona en Java 6 y ya no se ejecuta. El error, como dije, es:

Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: The frame is decorated at java.awt.Frame.setOpacity(Frame.java:960) at TranslucentWindowDemo$1.run(TranslucentWindowDemo.java:53) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311) ...

También intenté establecer el fondo (setBackground : Color) usando un Color con un valor Alpha personalizado ( new Color(int, int, int, Alpha) ) pero arroja exactamente el mismo error. Establecer la transparencia de un JPanel esta manera no funcionará, ya que aún estará en el JFrame , que no es transparente.

No pude encontrar ninguna otra respuesta en Stack Overflow que abordara correctamente este problema. De hecho, algunos sugirieron que esto podría solucionarse con:

JFrame.setDefaultLookAndFeelDecorated(true);

Pero ellos fueron mal informados de tal vez refiriéndose a Java 7, ya que lo he probado y el resultado es el mismo.

También traté de configurar manualmente Look and Feel:

try { for (final LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { UIManager.setLookAndFeel(info.getClassName()); break; } } } catch [...]

Y combinar esto con la solución sugerida anteriormente tampoco funcionó.

Consulte el código sobre el ejemplo que he vinculado anteriormente ( documento de Oracle ) para un MCVE, ya que ese es el que estoy usando.

De cualquier forma alrededor de esto?


Por lo que puedo decir, la respuesta básica es: no es posible , al menos con el aspecto y la sensación del Sistema . Como se indica en ¿Es el ejemplo de la ventana translúcida de los tutoriales de Java problemas para aquellos que juegan con jdk7? , los JavaDocs indican claramente que " la ventana debe estar sin decorar " para que setOpacity() .

Sin embargo, es posible hacerlo con la apariencia (fea) multiplataforma , que puede establecer progrmáticamente de la siguiente manera:

UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());

De hecho, como el aspecto y la sensación de plataforma cruzada podrían anularse a través de la configuración, lo más seguro sería establecerlo explícitamente en Metal de la siguiente manera:

UIManager.setLookAndFeel(new MetalLookAndFeel());

La razón por la que esto funciona, es que la implementación JDK de Frame.setOpacity() arroja una excepción cuando !isUndecorated() , y JFrame.frameInit() establece como no decorado cuando la apariencia getSupportsWindowDecorations() devuelve true . Luego llama a getRootPane (). SetWindowDecorationStyle () con JRootPane.FRAME , lo que indica que las decoraciones serán proporcionadas por el panel raíz en lugar del marco.

Según lo que puedo ver en el JDK, el aspecto y la sensación Metal es el único para el que getSupportsWindowDecorations() devuelve true , ya que es el único que lo reemplaza, y la implementación predeterminada simplemente devuelve false .

Sin embargo, algunos terceros lo ven y lo sienten también. Este es el caso, por ejemplo, para Tiny Look and Feel , como acabo de probar:

(Tenga en cuenta que tomé esta captura de pantalla en Ubuntu, ¡TinyLAF tiene un tema por defecto que se parece a Windows XP!)

Consulte también esta pregunta para obtener una lista de apariencia y sentimientos de terceros conocidos.


Intente agregar esta línea antes de crear la ventana JFrame:

JFrame.setDefaultLookAndFeelDecorated(true);

Exactamente esa línea, no reemplace JFrame al principio, necesita ser JFrame.

(También puede ver esta línea en los tutoriales que mencionó antes de crear la ventana).