如何在Netbeans中为Undecorated JFrame添加阴影 [英] How do I add shadow to Undecorated JFrame in Netbeans
问题描述
我想为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屋!