Friday, March 30, 2007

Transparent Window In Java Back With A BANG

Here is another version of code for Transparent Window in Java seems to be better than any of the previous version and has a blur effect to emulate the Vista look.Here is the code:

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

import java.awt.image.*;



public class TransparentBackground extends JComponent

implements ComponentListener, WindowFocusListener, Runnable {

private JFrame _frame;

private BufferedImage _background;

private long _lastUpdate = 0;

private boolean _refreshRequested = true;



private Robot _robot;

private Rectangle _screenRect;



private ConvolveOp _blurOp;

public TransparentBackground(JFrame frame) {

_frame = frame;



try {

_robot = new Robot();

} catch (AWTException e) {

e.printStackTrace();

return;

}



Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();

_screenRect = new Rectangle(dim.width, dim.height);



float[] my_kernel = {

0.10f, 0.10f, 0.10f,

0.10f, 0.20f, 0.10f,

0.10f, 0.10f, 0.10f};

_blurOp = new ConvolveOp(new Kernel(3, 3, my_kernel));



updateBackground();

_frame.addComponentListener(this);

_frame.addWindowFocusListener(this);

new Thread(this).start();

}


protected void updateBackground() {

_background = _robot.createScreenCapture(_screenRect);

}



protected void refresh() {

if (_frame.isVisible() && this.isVisible()) {

repaint();

_refreshRequested = true;

_lastUpdate = System.currentTimeMillis();

}

}


protected void paintComponent(Graphics g) {

Graphics2D g2 = (Graphics2D) g;



Point pos = this.getLocationOnScreen();



BufferedImage buf = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);

buf.getGraphics().drawImage(_background, -pos.x, -pos.y, null);



Image img = _blurOp.filter(buf, null);

g2.drawImage(img, 0, 0, null);



g2.setColor(new Color(255, 255, 255, 192));

g2.fillRect(0, 0, getWidth(), getHeight());

}

public void componentHidden(ComponentEvent e) {
refresh();
}



public void componentMoved(ComponentEvent e) {

repaint();

}



public void componentResized(ComponentEvent e) {

repaint();

}



public void componentShown(ComponentEvent e) {

repaint();

}

public void windowGainedFocus(WindowEvent e) {

refresh();

}



public void windowLostFocus(WindowEvent e) {

refresh();

}

public void run() {

try {

while (true) {

Thread.sleep(100);

long now = System.currentTimeMillis();

if (_refreshRequested && ((now - _lastUpdate) > 1000)) {

if (_frame.isVisible()) {

Point location = _frame.getLocation();

_frame.setLocation(-_frame.getWidth(), -_frame.getHeight());

updateBackground();

_frame.setLocation(location);

refresh();

}

_lastUpdate = now;

_refreshRequested = false;

}

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}



public static void main(String[] args) {

JFrame frame = new JFrame("Transparent Window");

TransparentBackground bg = new TransparentBackground(frame);



frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);



frame.getContentPane().add(bg);

frame.pack();

frame.setSize(200, 200);

frame.setLocation(500, 500);

frame.setVisible(true);

}

}


For Mac Users you need to simply write the following

import java.swing.*;
.......
public class TransparentBackground{

.......//code here
.......//code here
.......//code here
.......//code here
 frame.setBackground(new Color(0, 0, 0, 0));
}

7 comments:

Anonymous said...

This is cool but there are a few problems:
Sometimes the application jframe itself "captures" the grey loading JFrame, and not the desktop... just minimize the app and maximize it (linux).
A little more performance under wouldn't go amiss. If this is faster in java 6, well fine.

Anonymous said...

I see you are only capturing the screen sometimes, and not when the application moves around. I agree, but this is really fake "transparency" since the use case to this is seeing something that changes in the background. BTW when the app starts in linux jdk 1.5, the screen moves to the upper left corner before moving to the original position?

Ashish Lijhara said...

well first of all i would like you to leave your names...the second thing is do not worry i'll come up with something better....if you know about the yahoo widgets,it too works on the same technique wait for my next post

toonx said...

This is really cool! Thanks for the posting the code. The only problem I've noticed that no one else has addressed is that, if you have multiple monitors it only works in your main or default monitor.

adheep said...

Its really cool!!!!!
I liked it very much....


for those who havn't tried it
"GO for it, its really amazing"

Unknown said...

check this out! I tried it on x11 with good results:

import java.awt.*;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;

public class BGTest3
{

public static void main(final String[] args) throws AWTException, InterruptedException
{
GraphicsConfiguration c=null;
for(GraphicsConfiguration a:GraphicsEnvironment.getLocalGraphicsEnvironment()
.getScreenDevices()[0].getConfigurations())
if(a.getColorModel().getPixelSize()==32)
{
c=a;
break;
}
final Frame frame = new Frame("Transparent Window",c);
frame.setIgnoreRepaint(true);
frame.setVisible(true);
frame.setSize(300, 300);
BufferedImage b=new BufferedImage(300,300,BufferedImage.TYPE_INT_ARGB);
int[] ar=new int[256*256];
for(int x=0;x<256;++x)
for(int y=0;y<256;++y)
ar[x+256*y]=x*256*256*256+y*(65536+256+1);
b.setRGB(0, 0, 256, 256, ar, 0, 256);
frame.createBufferStrategy(1);
BufferStrategy bs = frame.getBufferStrategy();
Graphics2D g=(Graphics2D)bs.getDrawGraphics();
g.setComposite(AlphaComposite.Src);
for(int x=0;x<10;++x)
{
g.drawImage(b, 0,0,null);
bs.show();
Thread.currentThread().sleep(1000);
}
frame.dispose();
}
}

Anonymous said...

Who knows where to download XRumer 5.0 Palladium?
Help, please. All recommend this program to effectively advertise on the Internet, this is the best program!