12

Here's the example.

If you build and run TranslucentWindow in let's say, NetBeans IDE 7.0, which supports jdk7, you'll get the following exception:

Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: The frame is decorated
    at java.awt.Frame.setOpacity(Frame.java:960)
    at main.TranslucentWindow.<init>(TranslucentWindow.java:23)
    at main.TranslucentWindow$1.run(TranslucentWindow.java:47)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
    at java.awt.EventQueue.access$000(EventQueue.java:101)
    at java.awt.EventQueue$3.run(EventQueue.java:666)
    at java.awt.EventQueue$3.run(EventQueue.java:664)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
BUILD SUCCESSFUL (total time: 1 second)

According to this stack trace, the offending line is tw.setOpacity(0.55f). But, as the error indicates, if you invoke setUndecorated(true) on the frame, then it won't throw the exception and will create a translucent window, albeit without any decoration (which is a pain). Is this normal? Shouldn't this code run right "out-of-the-box"? Am I overlooking something?

EDIT

Why does their translucent window appear decorated, or is this custom rendering?

What it is...

enter image description here

What it should be...

enter image description here

mKorbel
  • 109,525
  • 20
  • 134
  • 319
mre
  • 43,520
  • 33
  • 120
  • 170

5 Answers5

18

Right from the JavaDocs for java.awt.frame.setOpacity() in JDK7:

The following conditions must be met in order to set the opacity value less than 1.0f:

  • The TRANSLUCENT translucency must be supported by the underlying system
  • The window must be undecorated (see setUndecorated(boolean) and Dialog.setUndecorated(boolean))
  • The window must not be in full-screen mode (see GraphicsDevice.setFullScreenWindow(Window))

If the requested opacity value is less than 1.0f, and any of the above conditions are not met, the window opacity will not change, and the IllegalComponentStateException will be thrown.

The behavior that you are seeing is documented and is expected behavior.

Thomas Owens
  • 114,398
  • 98
  • 311
  • 431
  • @Thomas, doh! :( ... well, glad it's in the Javadoc! :) – mre Jun 06 '11 at 23:53
  • Unfortunately, I have very little experience with JDK7. I just started looking at it just because NetBeans 7 has support for it. I spent about 20 minutes poking around. – Thomas Owens Jun 07 '11 at 00:03
  • @Thomas, likewise. this just happened to be one of the first items that I set my gaze upon. appreciate the help thus far. :) – mre Jun 07 '11 at 00:05
  • 1
    The only three things I can think of are (1) it's a 'shop, (2) for some reason, the limit on undecorated windows wasn't always there and this was captured before that was in place, or (3) you can set decorated back after you make the window translucent. But I wouldn't bet any money on any of them...I wish I could help more. – Thomas Owens Jun 07 '11 at 00:08
  • @Thomas, my first guess was (1), but (2) also sounds reasonable haha...it's just unfortunate that they're falsely advertising... :/ to me, undecorated windows have far less appeal. – mre Jun 07 '11 at 00:09
  • unforunate behaviour change - breaks existing applications :-( – kleopatra Sep 09 '11 at 09:19
  • appears from http://stackoverflow.com/questions/7353799/is-it-possible-to-have-a-translucent-windows-in-java-7-including-a-title-bar that if you use the Java look and feel then you can have a title bar still. yipes. – rogerdpack Sep 13 '11 at 22:07
6

This is a verified bug. I have sent Oracle information on their sample code failing using the default install of JDK 1.7.0 or JRE7. Using the source code below compiled into TranslucentWindow.java, it fails and produces the exception initially indicated above.

From web page Oracle's Translucency / Shaped Windows Page

// Taken from http://download.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html#uniform 
import java.awt.*;
import javax.swing.*;
import static java.awt.GraphicsDevice.WindowTranslucency.*;

public class TranslucentWindow extends JFrame {
public TranslucentWindow() {
    super("TranslucentWindow");
    setLayout(new GridBagLayout());

    setSize(300,200);
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Add a sample button.
    add(new JButton("I am a Button"));
}

public static void main(String[] args)  {
        // Determine if the GraphicsDevice supports translucency.
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();

        //If translucent windows aren't supported, exit.
        if (!gd.isWindowTranslucencySupported(TRANSLUCENT))
    {
        System.err.println("Translucency is not supported");
        System.exit(0);
    }

    // Create the GUI on the event-dispatching thread
    SwingUtilities.invokeLater(new Runnable()
    {
        @Override
        public void run()
        {
            TranslucentWindow tw = new TranslucentWindow();
            // Set the window to 55% opaque (45% translucent).
            tw.setOpacity(0.55f);
            // Display the window.
            tw.setVisible(true);
        }
    });
}

}

Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: The frame is decorated
    at java.awt.Frame.setOpacity(Frame.java:960)
    at TranslucentWindow$1.run(TranslucentWindow.java:38)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
    at java.awt.EventQueue.access$000(EventQueue.java:101)
    at java.awt.EventQueue$3.run(EventQueue.java:666)
    at java.awt.EventQueue$3.run(EventQueue.java:664)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Rick Hodgin
  • 657
  • 2
  • 8
  • 15
  • 2
    Where is the bug report so others can see it? I have noticed that with jre6 I get this exception "sometimes" and other times it shows the full JFrame translucent (as his "should be" example does). http://www.iteye.com/topic/1113045 seems to imply it is a "bug" in jdk6 that it was allowed, as also http://stackoverflow.com/questions/4631021/how-to-set-transparent-background-of-jdialog – rogerdpack Sep 08 '11 at 19:50
  • 1
    It wasn't an official bug report in their bug reporting system, but an email to the documentation page maintainers about that page having errant code. I never heard back from them, but the email went to 'javasedocs_us@oracle.com'. – Rick Hodgin Sep 12 '11 at 21:27
  • There's no official bug report, and yet you call it a *verified* bug?? – arkon Aug 27 '12 at 04:51
  • 2
    Yes. It's replicable. It's obvious. It deviates from published behavior. It also appeared in 1.7.0 following new transparency coding requirements. The same code in 1.6.x works fine. – Rick Hodgin Aug 29 '12 at 12:34
  • I think that it still works if you call setUndecorated(true) or setDefaultLookAndFeelDecorated(true) first. Which is weird since it didn't need to in jdk6. Looks like you can kind of reproduce the old behavior, see http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html for jdk7 options. But it's lame it changed... – rogerdpack Sep 04 '13 at 20:40
2

I think you need to setUndecorated before setBackground this will fix the problem

Benjemaa
  • 21
  • 3
2

Use com.sun.awt.AWTUtilities.setWindowOpacity(w, 0.5f) in JDK 7.

See here.

McGarnagle
  • 101,349
  • 31
  • 229
  • 260
0

Hi the problem with this code is that it is missing the following line of code in the main() method:

JFrame.setDefaultLookAndFeelDecorated(true);

It should go right after the code that checks if translucent windows aren't supported and exits:

    //If translucent windows aren't supported, exit.
    if (!gd.isWindowTranslucencySupported(TRANSLUCENT)) {
        System.err.println(
            "Translucency is not supported");
            System.exit(0);
    }

    JFrame.setDefaultLookAndFeelDecorated(true);

    // Create the GUI on the event-dispatching thread
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            TranslucentWindow tw = new TranslucentWindow();

            // Set the window to 55% opaque (45% translucent).
            tw.setOpacity(0.55f);

            // Display the window.
            tw.setVisible(true);
        }
    });

Also, the image of the uniform translucent image is misleading because it uses the java look and feel. Instead the image should use the Windows system look and feel (assuming you're on Windows). If you try to use the Java look and feel (i.e., JFrame.setDefaultLookAndFeelDecorated(false);), then it will throw the same error as before. I was hoping that the translucent window would work with the Java look and feel, but I don't think this is possible.

kimbaudi
  • 13,655
  • 9
  • 62
  • 74
  • JFrame.setDefaultLookAndFeelDecorated(false); does not fix anything. – arkon Aug 27 '12 at 05:05
  • 1
    for me setting it to JFrame.setDefaultLookAndFeelDecorated(true) avoids the particular error in question (make sure to do this before creating the frame, see http://docs.oracle.com/javase/6/docs/api/javax/swing/JFrame.html#setDefaultLookAndFeelDecorated(boolean) – rogerdpack Sep 04 '13 at 20:51
  • JFrame.setDefaultLookAndFeelDecorated(true) and JDialog.setDefaultLookAndFeelDecorated(true) only work with some LookAndFeels. The WindowsLookAndFeel for example does not seem to use these Properties. – Adrodoc Feb 14 '16 at 23:48