请耐心等待,我还是个初学者,请不要发表粗鲁的评论。
所以这个问题的目标是让我学习如何将已经透明的 JFrame 的背景设置为模糊。这就是我现在所拥有的。

正如您所看到的,它是透明的,但并不模糊。我在想也许 Java 有一些进程可以模糊 JAR 中的图像并将其用作背景而不改变原始图像。所以我看了又看,但没有发现任何对我有帮助的东西。
如上所示,JFrame 的背景是一个没有文本的标签,而是将“背景图像”作为标签的图标。
JAR 的组织:
META-INF(folder) > MANIFEST.MF
SystemInfo(folder) > classes and background image
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止的代码,但它不起作用。
setOpacity(); // sets opacity of the background
Color c = Color.WHITE; // default color
setColor(c);
//background = (new JLabel((Icon) new ImageIcon(a)));
BufferedImage mshi = null;
try{mshi = ImageIO.read(new File("SystemInfo/black.png"));}catch(Exception e){e.printStackTrace();}
BufferedImage databuf = new BufferedImage(mshi.getWidth(null),
mshi.getHeight(null),
BufferedImage.TYPE_INT_BGR);
Graphics g = databuf.getGraphics();
g.drawImage(mshi, 455, 255, null);
float[] blurKernel = {
1 / 9f, 1 / 9f, 1 / 9f,
1 / 9f, 1 / 9f, 1 / 9f,
1 / 9f, 1 / 9f, 1 / 9f
};
BufferedImageOp blur = new ConvolveOp(new Kernel(3, 3, blurKernel));
mshi = blur.filter(mshi, new BufferedImage(mshi.getWidth(),
mshi.getHeight(), mshi.getType()));
g.dispose();
//background = (new JLabel((Icon) new ImageIcon(mshi)));
background.setIcon((Icon)new JLabel(new ImageIcon(mshi)));
Run Code Online (Sandbox Code Playgroud)
上述代码产生的错误:
javax.imageio.IIOException: Can't read input file!
at javax.imageio.ImageIO.read(ImageIO.java:1301)
at SystemInfo.GuiMain.cinitComponents(GuiMain.java:150)
at SystemInfo.GuiMain.<init>(GuiMain.java:30)
at SystemInfo.GuiMain$8.run(GuiMain.java:256)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at SystemInfo.GuiMain.cinitComponents(GuiMain.java:152)
at SystemInfo.GuiMain.<init>(GuiMain.java:30)
at SystemInfo.GuiMain$8.run(GuiMain.java:256)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
Run Code Online (Sandbox Code Playgroud)
如果需要,可以使用 setOpacity(); 功能:
float fOpacity = (float)opacity/10;
String sOpacity = Float.toString(fOpacity)+"f";
this.setOpacity(Float.parseFloat(sOpacity));
Run Code Online (Sandbox Code Playgroud)
我的主要目标是让 JFrame 生成如下内容:

正如您所看到的,该框架稍微模糊了计算机背景并且是透明的。
谢谢大家。
Java 可以使用您拥有的代码来模糊图像 - 问题是 Java 无法看到窗口“下方”的图像,因此它将模糊空白图像。
窗口半透明是通过本机操作系统实现的。要获得模糊效果,我没有看到简单的方法。我的意思是这将非常困难。您可以尝试以下几件事:
java.awt.Robot捕捉窗口下方的内容,然后对其使用模糊。陷阱:您需要在捕获时隐藏窗口几毫秒,这可能会被用户注意到,并且每次背景发生变化时都需要执行此操作,这可能会涉及轮询。 但最终,鉴于这些技术相当先进,并且您说您是初学者(尽管您使用图像 I/O 成功地处理了模糊),您可能只想使用半透明窗口。
(编辑:添加 Windows 示例)
对于Windows,你可以使用JNA来调用DwmEnableBlurBehindWindow,效果很好。您必须拥有 Java 7 或更高版本才能正常工作。
例子:
package dwmtest;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.util.Arrays;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import com.sun.jna.Native;
import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
public class DwmWindow extends JFrame
{
public static void main(String... args)
throws Exception
{
JFrame.setDefaultLookAndFeelDecorated(true);
DwmWindow f = new DwmWindow();
f.setSize(600, 500);
f.setBackground(new Color(0,0,0,0));
f.setTitle("Hello");
TranslucentPanel panel = new TranslucentPanel();
panel.setLayout(new BorderLayout());
JLabel label = new JLabel("My background is blurry!");
label.setFont(new Font("Dialog", Font.BOLD, 48));
panel.add(label, BorderLayout.CENTER);
f.add(panel);
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
f.setVisible(true);
HWND hwnd = new HWND(Native.getWindowPointer(f));
Dwmapi.DWM_BLURBEHIND pBlurBehind = new Dwmapi.DWM_BLURBEHIND();
pBlurBehind.dwFlags = Dwmapi.DWM_BB_ENABLE;
pBlurBehind.fEnable = true;
pBlurBehind.fTransitionOnMaximized = false;
Dwmapi.INSTANCE.DwmEnableBlurBehindWindow(hwnd, pBlurBehind);
}
private static class TranslucentPanel extends JPanel
{
@Override
protected void paintComponent(Graphics g)
{
if (g instanceof Graphics2D) {
final int R = 240;
final int G = 240;
final int B = 240;
Paint p = new GradientPaint(0.0f, 0.0f, new Color(R, G, B, 0), 0.0f, getHeight(), new Color(R, G, B, 255), true);
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(p);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
}
}
public static interface Dwmapi extends StdCallLibrary
{
Dwmapi INSTANCE = (Dwmapi)Native.loadLibrary("Dwmapi", Dwmapi.class, W32APIOptions.UNICODE_OPTIONS);
int DWM_BB_ENABLE = 0x00000001;
boolean DwmEnableBlurBehindWindow(HWND hWnd, DWM_BLURBEHIND pBlurBehind);
public static class DWM_BLURBEHIND extends Structure
{
public int dwFlags;
public boolean fEnable;
public IntByReference hRgnBlur;
public boolean fTransitionOnMaximized;
@Override
protected List getFieldOrder()
{
return Arrays.asList("dwFlags", "fEnable", "hRgnBlur", "fTransitionOnMaximized");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您有支持 Aero 的 Windows 计算机,您将得到模糊的背景:

如果您没有 Aero 功能,它将退回到半透明而不会模糊。
面板背景的 Alpha 值控制哪些区域可以透视,哪些区域不能透视。在面板上绘制更复杂的背景可以产生孔或其他图案等效果。如果您需要均匀的半透明背景而不是渐变效果,请使用具有适当 alpha 值的简单背景颜色。