半透明的JFrame边框 JDK 7

14
我在询问关于半透明JFrame边框的问题(见此处),我得到了非常好的答案,但不幸的是,给出的答案只能在JDK 6上完美运行,而在JDK 7上则不能。有什么办法可以让它在JDK 7上运行?
在JDK 6中,它看起来像这样: enter image description here 而在JDK 7中: enter image description here 我的代码看起来像这样:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.border.AbstractBorder;


public class ShadowBorder extends AbstractBorder {

private static final int RADIUS = 30;
private static BufferedImage shadowTop;
private static BufferedImage shadowRight;
private static BufferedImage shadowBottom;
private static BufferedImage shadowLeft;
private static BufferedImage shadowTopLeft;
private static BufferedImage shadowTopRight;
private static BufferedImage shadowBottomLeft;
private static BufferedImage shadowBottomRight;
private static boolean shadowsLoaded = false;

public ShadowBorder() {
    if (!shadowsLoaded) {
        try {
            shadowTop = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-top.png"));
            shadowRight = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-right.png"));
            shadowBottom = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-bottom.png"));
            shadowLeft = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-left.png"));

            shadowTopLeft = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-top-left.png"));
            shadowTopRight = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-top-right.png"));
            shadowBottomLeft = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-bottom-left.png"));
            shadowBottomRight = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-bottom-right.png"));

            shadowsLoaded = true;
        } catch (IOException ex) {
            Logger.getLogger(ShadowBorder.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

@Override
public boolean isBorderOpaque() {
    return false;
}

@Override
public Insets getBorderInsets(Component c) {
    return new Insets(RADIUS, RADIUS, RADIUS, RADIUS);
}

@Override
public Insets getBorderInsets(Component c, Insets insets) {
    insets.top = RADIUS;
    insets.left = RADIUS;
    insets.bottom = RADIUS;
    insets.right = RADIUS;

    return insets;
}

@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
    Graphics2D g2d = (Graphics2D) g.create();
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, 1f));

    int recWidth = width - (2 * RADIUS);
    int recHeight = height - (2 * RADIUS);
    int recX = width - RADIUS;
    int recY = height - RADIUS;

    //edges
    g2d.drawImage(shadowTop.getScaledInstance(recWidth, RADIUS, Image.SCALE_REPLICATE), RADIUS, 0, null);
    g2d.drawImage(shadowRight.getScaledInstance(RADIUS, recHeight, Image.SCALE_REPLICATE), recX, RADIUS, null);
    g2d.drawImage(shadowBottom.getScaledInstance(recWidth, RADIUS, Image.SCALE_REPLICATE), RADIUS, recY, null);
    g2d.drawImage(shadowLeft.getScaledInstance(RADIUS, recHeight, Image.SCALE_REPLICATE), 0, RADIUS, null);

    //corners
    g2d.drawImage(shadowTopLeft, 0, 0, null);
    g2d.drawImage(shadowTopRight, recX, 0, null);
    g2d.drawImage(shadowBottomLeft, 0, recY, null);
    g2d.drawImage(shadowBottomRight, recX, recY, null);

}
}

非常感谢!


1
你有检查过 Bug 数据库吗?顺便说一句,截图很棒。+1 - Andrew Thompson
尝试在谷歌上搜索这个主题,但没有成功。 - Jay Gridley
2个回答

3

我刚刚解决了我的问题。 问题在于,JDK 7将来自JDK6的AWTUtilities.setWindowOpaque()方法实现为setBackground()方法,而我(NetBeans这样做了:-))在不同的地方设置JFrame的默认背景色,因此将背景设置为new Color(0, 0, 0, 0);使JFrame透明,现在一切都好了。


2

如果有人偶然发现了这个帖子并想要自己的透明窗口,我设计了这个示例。由于网上提供的信息非常少,我几乎要折断腿才能想出一个只是运行而不使用图像文件或其他东西的方案。(结合了站点上的不同示例)

public class GradientTranslucentWindowDemo
{
    public static void main(String[] args)
    {
        // Create the GUI on the event-dispatching thread
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                final JFrame f = new JFrame("Per-pixel translucent window");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                f.setUndecorated(true);
                f.setBackground(new Color(0, 0, 0, 0));

                final BufferedImage backrgoundImage = makeBackrgoundImage(400, 400);

                JPanel panel = new JPanel()
                {
                    @Override
                    public void paintComponent(Graphics g)
                    {
                        super.paintComponent(g);
                        if (g instanceof Graphics2D)
                        {

                            g.drawImage(backrgoundImage, 0, 0, null);
                        }
                    }
                };
                panel.setOpaque(false);
                f.setContentPane(panel);

                f.setLayout(new GridBagLayout()); // Centers the button
                f.add(new JButton(new AbstractAction("Close")
                {
                    @Override
                    public void actionPerformed(ActionEvent e)
                    {
                        f.dispose();
                    }
                }));

                f.setBounds(100, 100, 400, 400);
                f.setVisible(true);
            }
        });
    }

    static BufferedImage makeBackrgoundImage(int w, int h)
    {
        BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);

        // Draw something transparent
        Graphics2D g = img.createGraphics();
        g.setPaint(new RadialGradientPaint(new Point2D.Float(w / 2, h / 2), (w + h) / 4, new float[]{0, 1}, new Color[]{Color.RED, new Color(1f, 0, 0, 0)}));
        g.fillRect(0, 0, w, h);
        g.setPaint(Color.RED);
        g.drawRect(0, 0, w - 1, h - 1);
        g.dispose();

        return img;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接