Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set opacity of a decorated JFrame in Java 8

I would like to know how to get a transparent JFrame in the latest version of Java.

Currently, you can only use

<JFrame>.setOpacity();

if the frame is not decorated.

I have no use for an undecorated frame, so I'd like to know how to go around this restriction and set the opacity of the frame to 0.5f while still keeping the title bar, resize options etc.

I have read the docs here: http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html. The code only worked on Java 6 and no longer runs. The error, as I said, is:

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)
    ...

I have also tried setting the background (setBackground : Color) using a Color with custom Alpha value (new Color(int, int, int, Alpha)) but it throws the exact same error. Setting the transaprency of a JPanel this way won't work, as it will still lay on the JFrame, which is not transparent.

I could find no other answer on Stack Overflow that correctly addressed this issue. In fact, a few suggested that this could be fixed with:

JFrame.setDefaultLookAndFeelDecorated(true);

But they were misinformed of perhaps referring to Java 7, as I have tested it and the result is just the same.

I have also tried to manually set the Look And Feel:

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

} catch [...] 

And combining this with the solution suggested above also did not work.

Please refer to the code over to the example I linked above (Oracle doc) for a MCVE, as that is the one I'm using.

Any way around this?

like image 376
Joey Allieston Avatar asked Sep 16 '16 19:09

Joey Allieston


2 Answers

As far as I can tell, the basic answer is: it is not possible, at least with the System look and feel. As indicated in Is The Java Tutorials Translucent Window example giving trouble to those playing with jdk7?, the JavaDocs clearly indicate that “the window must be undecorated” for setOpacity() to work.

It is however possible to do it with the (ugly) Cross-platform look and feel, that you can progrmmatically set as follows:

UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());

In fact, as the cross-platform look and feel could be overridden through configuration, the safest would actually be to set it explicitly to Metal as follows:

UIManager.setLookAndFeel(new MetalLookAndFeel());

The reason this works, is that the JDK implementation of Frame.setOpacity() throws an exception when !isUndecorated(), and JFrame.frameInit() sets itself as undecorated when the look and feel's getSupportsWindowDecorations() returns true. It then calls getRootPane().setWindowDecorationStyle() with JRootPane.FRAME, indicating that the decorations will be provided by the root pane instead of the frame.

From what I can see in the JDK, the Metal look and feel is the only one for which getSupportsWindowDecorations() returns true, as it is the only one which overrides it, and the default implementation simply returns false.

However, some third-party look and feels support it too. This is the case for instance for the Tiny Look and Feel, as I just tried:

TranslucentWindowDemo with TinyLAF

(Note that I took this screenshot on Ubuntu, TinyLAF just so happens to have a default theme that looks like Windows XP!)

See also this question for a list of known third-party look and feels.

like image 156
Didier L Avatar answered Sep 27 '22 19:09

Didier L


Try adding this line before creating the JFrame window:

JFrame.setDefaultLookAndFeelDecorated(true);

Exactly that line, don't replace JFrame in the beggining, it needs to be JFrame.

(You can also spot this line in the tutorials you mentioned precicely placed before creating the window).

like image 34
chari Muvilla Avatar answered Sep 27 '22 19:09

chari Muvilla