如何在 Netbeans 中向 Undecorated JFrame 添加阴影

2024-02-01

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


这有点“作弊”。这不会在窗口后面产生阴影,而是在内容后面产生阴影。

这种方法不仅使窗口不被装饰,而且变得透明。替换的“内容窗格”被部分填充,允许阴影效果“出现”在其后面。

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;
    }
}

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

该面板是透明的并且具有EmptyBorder应用于。这可以确保添加到其中的任何内容都适合我们想要的区域。

接下来,我们生成一个BufferedImage它代表组件的整个可用空间,但我们只填充“可视”区域。我们对其应用阴影并将其绘制到组件上。

这个例子利用了GaussianFilter from JHLabs http://www.jhlabs.com/ip/filters/index.html

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

对于更复杂的例子,你可以看看Java:在图像上创建阴影效果 https://stackoverflow.com/questions/14655643/java-create-shadow-effect-on-image/14656403#14656403

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Netbeans 中向 Undecorated JFrame 添加阴影 的相关文章

随机推荐

  • Delphi 2010 中的 Indy IdHttp Post 问题

    我对 Indy IdHttp Post 方法有问题 使用 Delphi 2007 编译的函数 CallRpc 工作正常 但使用 Delphi 2010 编译的相同代码会引发异常 当我将 Delphi 2007 Indy TIdHttp 更改
  • 使用 Swift 3 停止预定定时器,即使定时器为零,定时器也会继续触发

    我们调用startTimer函数来启动一个定时器 当我们想要停止它时 我们调用 stopTimerTest 函数 但在调用 stopTimer 函数后 timerTestAction 继续触发 为了检查计时器条件 我们使用 print 并在
  • 通过引用设置接口参数

    我很难理解如何设置作为指针传递的接口值 我正在尝试完成以下任务 import fmt var Stuff map string interface func main var num int Stuff key 9001 get key n
  • 在asp.net mvc中一次更新多条记录

    我正在尝试使用制作一个网站asp net mvc 4 EF6我想一次更新多行 但由于某种原因 它不起作用 我收到这样的错误 System NullReferenceException 未将对象引用设置为对象的实例 这是我的代码 控制器 Ht
  • 展平 JavaScript 对象以作为查询字符串传递

    我有一个 javascript 对象 需要将其展平为字符串 以便可以作为查询字符串传递 我该怎么做 IE cost 12345 insertBy testUser 会成为cost 12345 insertBy testUser 我不能使用
  • 在 Scala / Spark 中将文件从一个文件夹移动到 HDFS 上的另一个文件夹

    我有两个路径 一个用于文件 一个用于文件夹 我想将文件移动到 HDFS 上的该文件夹中 我怎样才能在 Scala 中做到这一点 我也在用 Spark 如果相同的代码也适用于 Windows 路径 就像在 HDFS 上读取 写入文件一样 但不
  • 对 WTForms form.errors 字典进行排序

    forms errors 字典似乎是按字段名称排序的 而不是按 它们在表格本身中声明的顺序 E g class ProductForm Form code TextField Code validators Required descrip
  • 构建错误 -Ionic Cordova 在 Android 上失败 [重复]

    这个问题在这里已经有答案了 运行命令 ionic cordova build android stacktrace 时出现以下错误 generateDebugResources mergeDebugResources processDebu
  • 为什么 std::queue 不支持 clear() 函数?

    我有一个要求 对于一个函数 我将输入作为数字流 我的意思是 该函数在每次调用中都会继续使用单个数字进行调用 我在用std queue用于存储数字流 仅当满足某些条件时 我才需要处理一组收集的数字 如果不满足条件 我需要将所有元素放入队列中
  • 如何通过 Alchemy gcc 编译 ffmpeg?

    所以我创建了ffmpeg配置文件 使其成为纯C 平台无关 但只是理论上 所以我的配置很简单 0 6 1 0 6 3测试过 configure disable doc disable ffplay disable ffprobe disabl
  • CSS 网格布局最大内容在 Firefox 中无法按预期工作

    我使用 CSS 网格布局来创建页面的基本布局 并且我最初是在 Chrome 中工作的 我现在也在 Firefox 中对此进行了测试 并注意到一些我不理解的行为 并且似乎不符合我所理解的规范 我创建了一个显示该行为的简化示例 问题是搜索标题
  • Android 和 CommaTokenizer

    我需要一个 Tokenizer 用于 AutoCompleteTextview 它可以执行以下操作 当两个单词以空白字符分隔时 必须按原样进行识别 当用换行符分隔时 两个单词也必须被识别 按下 Enter 键 1 正在工作 但我怎样才能完成
  • laravel - 无法在控制器构造函数中获取会话

    在新的 Laravel 中 我无法在构造函数中获取会话 为什么 public function construct dd Session all this is empty array 然后下面 public function index
  • HTTP:200 OK 状态代码后回复期间出错

    作为 HTTP 1 1 服务器 我使用 200 OK 状态代码回复 GET 请求 然后开始将数据发送到客户端 在此发送过程中 发生错误 我无法完成 我无法发送新的状态代码 因为最终状态代码已发送 我应该如何让客户端知道发生了错误并且我无法继
  • 如何在 Python 3.x 中禁用 chrome webdriver 上的调试器?

    有人知道如何在 Python 3 6 中禁用 chrome webdriver 中的调试器 日志记录吗 我正在尝试遵循代码 但它不起作用 chrome options webdriver ChromeOptions chrome optio
  • 如何根据测试用例结果运行SoapUI中的指定步骤

    我在soapui中有一个项目 有更多的测试用例 运行每个测试用例后 我需要运行两个 http 请求之一 具体取决于步骤的结果 因此 如果测试用例中的一个或多个步骤失败 我需要运行 httprequest1 如果所有步骤都通过 我需要运行 h
  • 在andengine中使用Texture Packer加载动画

    我使用纹理打包器 我有 pvr ccz文件有10帧 我需要创建一个AnimatedSprite使用此动画 但 TexturePacker 扩展仅返回TextureRegion files 我怎样才能创造TiledTextureRegion从
  • CakePHP,从模型查询

    如何在 CakePHP 中执行 SQL 查询 我想做一些像这样的代码 employees this gt Employee gt find all 但介绍一下我自己的SQL语句 将执行 SQL 语句的函数插入模型中 public funct
  • VBA查找函数获取错误424需要对象[重复]

    这个问题在这里已经有答案了 我有代码获取错误 424 需要对象 lr Range O O Cells Rows Count 1 End xlUp Row For y 0 To UBound myVariable a myVariable y
  • 如何在 Netbeans 中向 Undecorated JFrame 添加阴影

    我想向 Undecorated jFrame 添加阴影 我不知道该怎么做 有人知道吗 这有点 作弊 这不会在窗口后面产生阴影 而是在内容后面产生阴影 这种方法不仅使窗口不被装饰 而且变得透明 替换的 内容窗格 被部分填充 允许阴影效果 出现