Java Tutorials半透明窗口示例给使用jdk7的人带来了麻烦吗?

mre*_*mre 9 java swing translucency java-7 netbeans7.0

这是一个例子.

如果你构建并运行TranslucentWindow支持jdk7的NetBeans IDE 7.0,你将得到以下异常:

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)
Run Code Online (Sandbox Code Playgroud)

根据这个堆栈跟踪,违规行是tw.setOpacity(0.55f).但是,正如错误所示,如果你setUndecorated(true)在框架上调用,那么它不会抛出异常并创建一个半透明的窗口,虽然没有任何装饰(这很痛苦).这是正常的吗?这段代码不应该"开箱即用"吗?我忽略了什么吗?

编辑

为什么他们的半透明窗口看起来是装饰的,还是这个自定义渲染?

这是什么...

在此输入图像描述

应该是什么......

在此输入图像描述

Tho*_*ens 16

JDK7中的java.awt.frame.setOpacity()JavaDocs开始:

要将不透明度值设置为小于1.0f,必须满足以下条件:

  • 底层系统必须支持TRANSLUCENT半透明
  • 窗口必须是未修饰的(参见setUndecorated(boolean)和Dialog.setUndecorated(boolean))
  • 窗口不能处于全屏模式(参见GraphicsDevice.setFullScreenWindow(Window))

如果请求的不透明度值小于1.0f,并且不满足上述任何条件,则窗口不透明度将不会更改,并且将抛出IllegalComponentStateException.

您看到的行为已记录在案,并且是预期的行为.


Ric*_*gin 6

这是一个已验证的错误。我已向 Oracle 发送了有关其示例代码在使用默认安装的 JDK 1.7.0 或 JRE7 时失败的信息。使用下面编译成 TranslucentWindow.java 的源代码,它会失败并产生上面最初指出的异常。

来自网页Oracle 的半透明/异形 Windows 页面

// 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);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

}

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)
Run Code Online (Sandbox Code Playgroud)

  • 错误报告在哪里以便其他人可以看到?我注意到,使用 jre6“有时”会出现此异常,而其他时候它会显示完整的 JFrame 半透明(正如他的“应该是”示例那样)。http://www.iteye.com/topic/1113045似乎暗示这是jdk6中允许的“错误”,http://stackoverflow.com/questions/4631021/how-to-set-transparent -jdialog 的背景 (2认同)
  • 是的。它是可复制的。很明显。它偏离已发布的行为。根据新的透明度编码要求,它也出现在 1.7.0 中。1.6.x 中的相同代码可以正常工作。 (2认同)