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

我想为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; } } 

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

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

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

该示例使用来自JHLabs的GaussianFilter

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

有关更复杂的事情的示例,您可以看一下Java:在图像上创建阴影效果