Be patient I\'m still a beginner, no rude comments please.
So the goal of this question is so I learn how to set the background of my already transparent JFrame to b
My first guess in "SystemInfo/black.png"
can't be referenced as File
because it's an embedded/internal resource, residing within your application Jar.
In order to read it (via ImageIO
) you will need to use something more like...
ImageIO.read(getClass().getResource("SystemInfo/black.png"))
Instead.
Secondly, blurring the image probably won't result in the effect you are looking for, as it won't have any effect of the how the content behind your window is actually painted.
Instead, you will need to capture the section of the screen below your window and blur that.
You can achieve this by using Robot
, but will need to make the window invisible when you grab the screen shot.
It will also not be a "live" update.
Java can blur an image using the code you have - the problem is that Java does not see the image 'underneath' your window so it will be blurring a blank image.
Window translucency is achieved through the native operating system. To get a blur effect, I don't see an easy way. And by that I mean it's going to be pretty darn difficult. A couple of things you might try:
java.awt.Robot
to capture what's underneath the Window, then use blur on that. Pitfalls: you need to hide your window for a few milliseconds while taking the capture which might be noticeable by the user, and you need to do this every time the background changes which will probably involve polling. But ultimately, given that these techniques are pretty advanced and you said you are a beginner (though you managed with the blurring using Image I/O OK) you might just want to settle with translucent windows.
(Edit: add example for Windows)
For Windows, you can use JNA to call DwmEnableBlurBehindWindow
and it works great. You must have Java 7 or later for this to work.
Example:
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");
}
}
}
}
If you have an Aero-capable Windows machine you will get a blurry background:
If you don't have Aero capability it will fall back to just being translucent without the blurriness.
The alpha values of the panel's background control which areas are see through and which not. A more sophisticated background painted in the panel could create effects like holes or other patterns. If you need a uniformly translucent background instead of the gradient effect, use a simple background color with an appropriate alpha value instead.