启动窗口在mac中不起作用

时间:2012-10-27 10:39:43

标签: java swing user-interface splash-screen

显示JAVA 6启动画面时出现问题我使用以下方法显示启动窗口。

File splashImageFile = new File(Constants.PATH_IMAGE + "splash.png");
        final BufferedImage img = ImageIO.read(splashImageFile);
        final JWindow window = new JWindow() {
            private static final long serialVersionUID = -132452345234523523L;

            @Override
            public void paint(Graphics g) {
                Graphics2D g2 = (Graphics2D) g.create();
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
                Rectangle windowRect = getBounds();
                try {
                    Robot robot = new Robot(getGraphicsConfiguration().getDevice());                        
                    BufferedImage capture = robot.createScreenCapture(new Rectangle(windowRect.x, windowRect.y, windowRect.width, windowRect.height));
                    g2.drawImage(capture, null, 0, 0);
                } catch (IllegalArgumentException iae) {
                    System.out.println("Argumets mis matched.\n" + iae.getMessage());
                } catch(SecurityException se){
                    System.out.println("Security permission not supported\n" + se.getMessage());
                } catch (AWTException ex) {
                    System.out.println("Exception found when creating robot.\n" + ex.getMessage());
                }
                g2.drawImage(img, 0, 0, null);
                g2.setFont(new Font("TimesRoman", Font.BOLD, 15));
                g2.drawString("Loading...", 320, 260);
                g2.dispose();
            }
        };
        window.setAlwaysOnTop(true);
        window.setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
        window.pack();
        window.setLocationRelativeTo(null);
        window.setVisible(true);
        window.repaint();

图像是png透明图像,因为我需要在窗口中使用圆角矩形。它适用于Win 7但在mac 10.8中。 Mac仍然显示矩形形状背景。它实际上似乎不是背景。有人可以告诉我可能导致什么。以下是每个平台的图像。

在Windows上

windows

在Mac上

mac

提前致谢。

编辑:

答案很棒,但我已经看到AWTUtilities并不总是获得系统支持。所以在一些系统中,回答方法可能会失败。难道没有正式的解决方案吗?我的意思是解决方案来自基础水平?

4 个答案:

答案 0 :(得分:6)

http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html#shaped 这显示了如何创建形状窗口

addComponentListener(new ComponentAdapter() {
            // Give the window an elliptical shape.
            // If the window is resized, the shape is recalculated here.
            @Override
            public void componentResized(ComponentEvent e) {
                setShape(new Ellipse2D.Double(0,0,getWidth(),getHeight()));
            }
        });

        setUndecorated(true);

他们说:从Java平台标准版6(Java SE 6)更新版本10开始,您可以为Swing应用程序添加半透明和整形窗口。

答案 1 :(得分:5)

正如已经开始声明的那样,从Java 1.6更新10开始,您可以访问com.sun.awt.AWTUtilities(私有API),它提供每像素分区支持。

enter image description here

这一切的一个技巧是确保将内容窗格设置为透明。

在Mac OS 10.7.5,10.8.2下测试;使用Java 1.6.0_37和1.7.0_06

public class TestWindowTransparency {

    public static void main(String[] args) {
        new TestWindowTransparency();
    }

    public TestWindowTransparency() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                SplashWindow window = new SplashWindow();
                window.setVisible(true);

            }
        });

    }

    public class SplashWindow extends JWindow {

        public SplashWindow() {

            ImageIcon icon = null;

            try {
                icon = new ImageIcon(ImageIO.read(getClass().getResource("/Splash02.png")));
            } catch (Exception e) {
                e.printStackTrace();
            }

            setAlwaysOnTop(true);
            JPanel content = new JPanel(new BorderLayout());
            content.setOpaque(false);
            setContentPane(content);

            JLabel lbl = new JLabel(icon);
            lbl.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getClickCount() == 2) {
                        dispose();
                    }
                }
            });

            add(lbl);

            if (!supportsPerAlphaPixel()) {
                System.out.println("Per Pixel Alpher is not supported by you system");
            }

            setOpaque(false);

            pack();
            setLocationRelativeTo(null);

        }

        public boolean supportsPerAlphaPixel() {
            boolean support = false;
            try {
                Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
                support = true;
            } catch (Exception exp) {
                exp.printStackTrace();
            }
            return support;
        }

        public void setOpaque(boolean opaque) {
            try {
                Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
                if (awtUtilsClass != null) {
                    Method method = awtUtilsClass.getMethod("setWindowOpaque", Window.class, boolean.class);
                    method.invoke(null, this, opaque);
                }
            } catch (Exception exp) {
                exp.printStackTrace();
            }
        }

        public void setOpacity(float opacity) {
            try {
                Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
                if (awtUtilsClass != null) {
                    Method method = awtUtilsClass.getMethod("setWindowOpacity", Window.class, float.class);
                    method.invoke(null, this, opacity);
                }
            } catch (Exception exp) {
                exp.printStackTrace();
            }
        }

        public float getOpacity() {
            float opacity = 1f;
            try {
                Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
                if (awtUtilsClass != null) {
                    Method method = awtUtilsClass.getMethod("getWindowOpacity", Window.class);
                    Object value = method.invoke(null, this);
                    if (value != null && value instanceof Float) {
                        opacity = ((Float) value).floatValue();
                    }
                }
            } catch (Exception exp) {
                exp.printStackTrace();
            }
            return opacity;
        }
    }
}

答案 2 :(得分:4)

要获得统一的解决方案,您应该使用Java7。每个像素半透明几乎是一个&#34;实验&#34; Java 6中的功能,并没有被认为是你可以依赖的东西(这就是AWTUtilities进入com.sun包的原因,which is not part of Java public API)。

然而,虽然我还没有Mac测试它,但是我看到人们报告将帧背景设置为Color(0,0,0,0)(最后一个参数是alpha频道)在MacOS为他们工作。我不清楚它是否在Windows中工作(几年前我不得不使用它),但我刚刚在Linux上测试过它并没有。

在Java 7中,半透明窗口完全受支持,并且在Windows,MacOS和Linux中完美运行。 JFrame有新的setOpacity(Alpha)方法(仅适用于未修饰的帧)和setColor(新的Color(R,G,B,Alpha))也在工作(它是等效的,并且只能用于未修饰的帧)。

如您所见,您无法依赖私有API AWTUtilities。在Java 6中,您还没有获得任何正式的解决方案&#34;对于这个问题,只有黑客,私有API和不确定性......我不知道它是否是一个选项,但你应该考虑切换到Java7,如果可以的话。

答案 3 :(得分:2)

正如我所说,某些系统可能不支持使用AWTUtilities,并且必须同意Eneko。我也这样做了如下。似乎有点类似于eneko的想法。我已经在Windows 7终极版和苹果mac os雪豹中进行了测试。它同时适用于两者。再次,如果这不适用于Linux,那么这也不是一个广泛适用的解决方案。希望有人可以发布这个答案。

final JWindow window = new JWindow() {
            private static final long serialVersionUID = -132452345234523523L;

            @Override
            public void paint(Graphics g) {
                Graphics2D g2 = (Graphics2D) g.create();
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                Rectangle windowRect = new Rectangle(getSize());
                g2.setColor(new Color(255, 255, 255, 0));
                g2.draw(new RoundRectangle2D.Float(windowRect.x, windowRect.y, windowRect.width, windowRect.height, 85, 85));
                g2.drawImage(img, 0, 0, null);
                g2.dispose();
            }
        };            
        window.setBackground(new Color(0,0,0,0));