【问题标题】:How to remove drop shadow of Java AWT Frame on OSX?如何在 OSX 上删除 Java AWT 框架的阴影?
【发布时间】:2012-11-24 23:17:48
【问题描述】:

是否可以在 OS X 上禁用 Java AWT 应用程序的投影? 我想创建一个透明窗口,效果很好,但我无法摆脱阴影。

如果我使用的是JFrame,则可以使用:

 JRootPane root = frame.getRootPane();
 root.putClientProperty( "Window.shadow", Boolean.FALSE );

AWT 帧是否有类似的可能性?

我使用框架Processing,我的代码如下所示:

void setup(){
  frame.removeNotify();
  frame.setUndecorated(true);
}

处理本身会创建主框架,这里是source

【问题讨论】:

    标签: java macos awt frame dropshadow


    【解决方案1】:

    这是一个简单的应用程序,它使用在 Java 7 下的 Max OS X 10.7.5 上运行的透明窗口(已在 Java 6 下运行)没有任何问题...

    分享一些代码,以便我们可以复制问题

    根据反馈更新

    我已经使用 JDK 1.7.0_07 和 1.6.0_37 在 Mac OS 10.7.5 和 10.8.2 上对此进行了测试

    不带和带Window.shadow 属性...

    在没有进行大量测试并且没有进一步信息的情况下,我建议您尽早拨打此电话。如果这不起作用,请在使窗口可见之前将其作为最后一次调用。

    这可能与 Java/AWT 如何连接到它的本地对等点有关,大概一旦建立连接,您将无法再影响这些类型的属性...

    public class TransparentFrame {
    
        public static void main(String[] args) {
            new TransparentFrame();
        }
    
        public TransparentFrame() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (Exception ex) {
                    }
                    // Use this to test the transparentancy API
                    //doTransparentFrame();
                    doDropShadow();
                }
    
            });
        }
    
        protected void doDropShadow() {
            String version = System.getProperty("java.version");
            System.out.println(version);
            JFrame frame = new JFrame("Testing");
            JRootPane root = frame.getRootPane();
            root.putClientProperty("Window.shadow", root);
            frame.setUndecorated(true);
            frame.setContentPane(new ContentPane());
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new ImagePane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        protected void doTransparentFrame() {
            JFrame frame = new JFrame("Testing");
            frame.setUndecorated(true);
            frame.setContentPane(new ContentPane());
    
            String version = System.getProperty("java.version");
            System.out.println(version);
            if (version.startsWith("1.7")) {
                frame.setBackground(new Color(0, 0, 0, 0));
            } else if (version.startsWith("1.6")) {
                if (supportsPerAlphaPixel()) {
                    setOpaque(frame, false);
                } else {
                    System.out.println("Per Pixel Alphering is not support with Java " + version);
                    System.exit(1);
                }
            } else {
                System.out.println("Per Pixel Alphering is not support with Java " + version);
                System.exit(1);
            }
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new ImagePane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public static boolean supportsPerAlphaPixel() {
    
            boolean support = false;
    
            try {
    
                Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
                support = true;
    
            } catch (Exception exp) {
            }
    
            return support;
    
        }
    
        public static void setOpaque(Window window, 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, window, opaque);
    
                }
    
            } catch (Exception exp) {
            }
    
        }
    
        public class ContentPane extends JPanel {
    
            public ContentPane() {
                setOpaque(false);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.setColor(Color.RED);
                g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
            }
    
        }
    
        public class ImagePane extends JPanel {
    
            private BufferedImage background;
            private BufferedImage offImage;
            private Ellipse2D offButton;
            private boolean mouseIn;
    
            public ImagePane() {
                setOpaque(false);
                try {
                    background = ImageIO.read(new File("tamagotchi400.png"));
                    offImage = ImageIO.read(new File("powerSmall.png"));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                offButton = new Ellipse2D.Float(212, 330, 25, 25);
                MouseAdapter handler = new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        if (e.getClickCount() == 1 && e.getButton() == MouseEvent.BUTTON1) {
                            if (offButton.contains(e.getPoint())) {
                                Window window = SwingUtilities.getWindowAncestor(ImagePane.this);
                                if (window != null) {
                                    window.dispose();
                                }
                            }
                        }
                    }
    
                    @Override
                    public void mouseMoved(MouseEvent e) {
                        Cursor cursor = Cursor.getDefaultCursor();
                        if (offButton.contains(e.getPoint())) {
                            cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
                        }
                        setCursor(cursor);
                    }
    
                    @Override
                    public void mouseEntered(MouseEvent e) {
                        mouseIn = true;
                        repaint();
                    }
    
                    @Override
                    public void mouseExited(MouseEvent e) {
                        mouseIn = false;
                        repaint();
                    }
    
                };
                addMouseListener(handler);
                addMouseMotionListener(handler);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return background == null ? new Dimension(400, 400) : new Dimension(background.getWidth(), background.getHeight());
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (background != null) {
                    Graphics2D g2d = (Graphics2D) g.create();
                    int x = (getWidth() - background.getWidth()) / 2;
                    int y = (getHeight() - background.getHeight()) / 2;
                    g2d.drawImage(background, x, y, this);
                    if (mouseIn && offImage != null) {
                        g2d.drawImage(offImage, (int) offButton.getX(), (int) offButton.getY(), this);
                    }
                    g2d.dispose();
                }
            }
    
        }
    
    }
    

    代码还包括透明度测试代码,用于测试 Java 1.7 和 Java 1.6_10+ 中现在可用的透明度 API。我已在多个项目中成功使用此代码,它比 AWT 机器人“hack”更简单,并提供了实时背景,但这是您需要做出的选择。

    更新

    使用java.awt.Frame进行演示

    public class TestTransparentFrame {
    
        public static void main(String[] args) {
            new TestTransparentFrame();
        }
    
        public TestTransparentFrame() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (Exception exp) {
                    }
    
                    Frame frame = new Frame("Test");
                    frame.setUndecorated(true);
                    setOpaque(frame, false);
                    frame.addWindowListener(new WindowAdapter() {
                        @Override
                        public void windowClosing(WindowEvent e) {
                            System.exit(0);
                        }
    
                    });
                    frame.setLayout(new BorderLayout());
                    frame.add(new ContentPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
    
            });
        }
    
        public class ContentPane extends JPanel {
    
            private BufferedImage background;
    
            public ContentPane() {
                try {
                    background = ImageIO.read(new File("duke.png"));
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
                setOpaque(false);
                JButton close = new JButton("Close");
                close.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        SwingUtilities.getWindowAncestor(ContentPane.this).dispose();
                    }
                });
                setBorder(new LineBorder(Color.RED));
                setLayout(new GridBagLayout());
                add(close);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return background == null ? new Dimension(200, 200) : new Dimension(background.getWidth(), background.getHeight());
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (background != null) {
                    g.drawImage(background, 0, 0, this);
                }
            }
    
        }
    
        public static boolean supportsPerAlphaPixel() {
    
            boolean support = false;
            String version = System.getProperty("java.version");
            if (version.startsWith("1.6")) {
                try {
                    Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
                    support = true;
                } catch (Exception exp) {
                }
            } else if (version.startsWith("1.7")) {
                try {
                    Class<?> winTransClass = Class.forName("java.awt.GraphicsDevice$WindowTranslucency");
                    Field field = winTransClass.getField("TRANSLUCENT");
    
                    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
                    GraphicsDevice gd = ge.getDefaultScreenDevice();
    
                    gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.TRANSLUCENT);
    
                    Method isWindowTranslucencySupported = GraphicsDevice.class.getMethod("isWindowTranslucencySupported", winTransClass);
                    System.out.println(isWindowTranslucencySupported);
    
                    Object value = isWindowTranslucencySupported.invoke(gd, field.get(null));
                    if (value instanceof Boolean) {
                        support = ((Boolean) value).booleanValue();
                    }
    
                } catch (Exception exp) {
                }
            }
            return support;
        }
    
        public static void setOpaque(Window window, boolean opaque) {
    
            String version = System.getProperty("java.version");
            if (version.startsWith("1.6")) {
                try {
                    Class<?> awtUtilsClass = Class.forName("com.sun.awt.AWTUtilities");
                    if (awtUtilsClass != null) {
                        Method method = awtUtilsClass.getMethod("setWindowOpaque", Window.class, boolean.class);
                        method.invoke(null, window, opaque);
                    }
                } catch (Exception exp) {
                }
            } else if (version.startsWith("1.7")) {
                Color color = UIManager.getColor("Panel.background");
                if (opaque) {
                    color = new Color(color.getRed(), color.getGreen(), color.getBlue());
                } else {
                    color = new Color(color.getRed(), color.getGreen(), color.getBlue(), 0);
                }
                window.setBackground(color);
            }
    
        }
    
    }
    

    使用 JDK 1.7.0_07 和 1.6.0_37 在 Windows 7 Java 1.6 和 1.7、Mac OS 10.7.5 和 10.8.2 上测试

    看来你对Java中的窗口层次结构不太了解

    Java 中的所有“窗口”都派生自 java.awt.Window

    JFrame 扩展 Frame 扩展 Window

    【讨论】:

    • 没有问题,就是不知道怎么去掉blanc AWT帧中的阴影。
    • 我在 Mac OS 上使用透明框架没有很多,它们不显示阴影。您能否分享一些代码,以便我们了解您是如何创建窗口的,以便我们可以复制它,这样我们也许可以提供更多帮助
    • 所以你的示例代码不会制作一个透明的框架,而是一个无框架的
    • 是的,我正在显示桌面的屏幕截图,看起来像是透明的。也有使用 AWTUtilities 创建透明框架的功能,但这些功能仅限于窗口。使用屏幕截图方法,创建一个“透明”框架对我有用......除了阴影。
    • 啊……现在在哪里得到一些 ;)
    【解决方案2】:

    使用这条线,它可以工作:

    AWTUtilities.setWindowOpaque(frame, false);
    

    Eclipse 会打印出一个警告,我不得不更改一些设置来实现它,所以我想可能有更好的方法。 我读到here,自 OS X 10.6 (Lion) 起支持此功能。

    【讨论】:

      【解决方案3】:

      似乎当你的框架没有对焦时,会触发阴影效果。尝试添加此代码,这样您的框架将无法获得焦点。

      frame.setFocusableWindowState(false);
      

      【讨论】:

        【解决方案4】:

        我今天在 OSX 上遇到了 JInternalFrame 的影子问题,我在另一个论坛上找到了这个解决方案(在 Java 11、Catalina 10.15 上验证)

        internalFrame.putClientProperty("JInternalFrame.frameType", "normal");
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-07
          • 1970-01-01
          • 2016-11-23
          • 2021-04-09
          • 2018-05-25
          • 2022-01-01
          相关资源
          最近更新 更多