如何在Netbeans中为Undecorated JFrame添加阴影 [英] How do I add shadow to Undecorated JFrame in Netbeans

查看:175
本文介绍了如何在Netbeans中为Undecorated JFrame添加阴影的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为Undecorated jFrame添加阴影。我不知道该怎么做。有人知道吗?

I want to add shadow to Undecorated jFrame. i have no idea about how to do that. anyone know about that?

推荐答案

这有点像作弊。这不会在窗口后面留下阴影,只会在内容后面留下阴影。

This is a bit of a "cheat". This doesn't make a drop shadow behind the window so much as makes a drop shadow behind the content.

此方法不仅使窗口不修饰,而且透明。替换内容窗格部分填充,允许阴影效果显示在其后面。

This method not only makes the window undecorated, but also transparent. The replacement "content pane" is partially filled allowing the shadow effect to "appear" behind it.

import com.jhlabs.image.GaussianFilter;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Transparency;
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.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class TestImageDropShadow {

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

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

                JFrame frame = new JFrame("Testing");
                frame.setUndecorated(true);
                frame.setBackground(new Color(0, 0, 0, 0));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setContentPane(new ShadowPane());
                frame.setLayout(new BorderLayout());
                frame.add(new JLabel(new ImageIcon("/you/own/pony")));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ShadowPane extends JPanel {

        private BufferedImage shadow;

        public ShadowPane() {
            setOpaque(false);
            setBorder(new EmptyBorder(10, 10, 10, 10));
        }

        @Override
        public void invalidate() {
            shadow = null;
            super.invalidate();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Insets insets = getInsets();
            int x = insets.left;
            int y = insets.top;
            int width = getWidth() - (insets.left + insets.right);
            int height = getHeight() - (insets.top + insets.bottom);
            if (shadow == null) {
                // Try and "guess" the amount of shadow we can show...
                int shadowWidth = Math.min(Math.min(insets.left, insets.top), Math.min(insets.right, insets.bottom));
                shadow = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
                Graphics2D g2d = shadow.createGraphics();
                g2d.setColor(getBackground());
                g2d.fillRect(0, 0, width, height);
                g2d.dispose();
                shadow = generateShadow(shadow, shadowWidth, Color.BLACK, 0.5f);
            }
            System.out.println(insets);
            g.drawImage(shadow, 0, 0, this);
            g.setColor(getBackground());
            g.fillRect(x, y, width, height);
        }

    }

    public static void applyQualityRenderingHints(Graphics2D g2d) {
        g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
        g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
    }

    public static BufferedImage createCompatibleImage(int width, int height) {
        return createCompatibleImage(width, height, Transparency.TRANSLUCENT);
    }

    public static BufferedImage createCompatibleImage(int width, int height, int transparency) {
        BufferedImage image = getGraphicsConfiguration().createCompatibleImage(width, height, transparency);
        image.coerceData(true);
        return image;
    }

    public static BufferedImage createCompatibleImage(BufferedImage image) {
        return createCompatibleImage(image, image.getWidth(), image.getHeight());
    }

    public static BufferedImage createCompatibleImage(BufferedImage image,
                    int width, int height) {
        return getGraphicsConfiguration().createCompatibleImage(width, height, image.getTransparency());
    }

    public static GraphicsConfiguration getGraphicsConfiguration() {
        return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
    }

    public static BufferedImage generateBlur(BufferedImage imgSource, int size, Color color, float alpha) {
        GaussianFilter filter = new GaussianFilter(size);

        int imgWidth = imgSource.getWidth();
        int imgHeight = imgSource.getHeight();

        BufferedImage imgBlur = createCompatibleImage(imgWidth, imgHeight);
        Graphics2D g2 = imgBlur.createGraphics();
        applyQualityRenderingHints(g2);

        g2.drawImage(imgSource, 0, 0, null);
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha));
        g2.setColor(color);

        g2.fillRect(0, 0, imgSource.getWidth(), imgSource.getHeight());
        g2.dispose();

        imgBlur = filter.filter(imgBlur, null);

        return imgBlur;
    }

    public static BufferedImage generateShadow(BufferedImage imgSource, int size, Color color, float alpha) {
        int imgWidth = imgSource.getWidth() + (size * 2);
        int imgHeight = imgSource.getHeight() + (size * 2);

        BufferedImage imgMask = createCompatibleImage(imgWidth, imgHeight);
        Graphics2D g2 = imgMask.createGraphics();
        applyQualityRenderingHints(g2);

        int x = Math.round((imgWidth - imgSource.getWidth()) / 2f);
        int y = Math.round((imgHeight - imgSource.getHeight()) / 2f);
        g2.drawImage(imgSource, x, y, null);
        g2.dispose();

        // ---- Blur here ---
        BufferedImage imgGlow = generateBlur(imgMask, (size * 2), color, alpha);

        return imgGlow;
    }
}

基本上这里发生的事情,我们首先做的是widnow透明。接下来,我们用我们自己的特殊 ShadowPane 替换内容窗格。

Basically what happens here, is we first make the widnow transparent. Next we replace the content pane with our own, special ShadowPane.

此面板是透明的,并且 EmptyBorder 已应用于。这可以确保添加到它的任何内容都适合我们想要的区域。

This panel is transparent and has an EmptyBorder applied to. This ensures that anything added to it will fit within the area we want.

接下来,我们生成一个 BufferedImage 表示组件的整个可用空间,但我们只填充可查看区域。我们对此应用阴影并将其绘制到组件。

Next, we generate a BufferedImage which represents the entire available space of the component, but we only fill the "viewable" area. We the apply a drop shadow to this and paint it to the component.

此示例使用 GaussianFilter 来自 JHLabs

严格地说,你不需要它,但它确实提供了一个很好的模糊效果

Strictly speaking, you don't need it, but it does provide a nice "fuzzy" effect

对于一些更复杂的例子,你可以看看在 Java:在图像上创建阴影效果

For an example of something little more complex, you could take a look at Java: create shadow effect on image

这篇关于如何在Netbeans中为Undecorated JFrame添加阴影的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆