you have probably seen this before, it is another screenshot-based implementation of a translucent window. (is there any other way besides JNI? if so, this is news to me.)
some things to note about it:
- initialises with a string for the window image(found using getClass().getResource() on it)
- it doesn’t refresh its background, except when being dragged, and even then, it only grabs a shot of the area it is moving into. good, because the window never flickers bad because the background more easily gets out of sync if you never move it.
- you can put ordinary components onto its ContentPane
- uses double buffering so should be very flicker-free.
- performance is better with GIF images than PNG images. (ie, transparency is much faster than translucency)
- for best results, use with setUndecorated(true) to hide the JFrame’s window decorations.
a picture is worth a thousand words as they say:
http://juddman.googlepages.com/bgw-example.png
here is the class file:
BackgroundWindow.java
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;
import javax.imageio.*;
import java.awt.event.*;
class InvisiblePanel extends JPanel
{
	public void paint(Graphics g)
	{
		paintChildren(g);
	}
}
public class BackgroundWindow extends JFrame implements MouseListener, MouseMotionListener
{
	final int     delay = 1;
	int           x, y, w, h,
	              oldX, oldY,
	              mouseX = 0,
	              mouseY = 0;
	long          time;
	
	BufferedImage image,
	              bgImage,
	              bgBuffer,
	              windowBuffer,
	              nativeImage;
	Robot         rob;
	
	public BackgroundWindow(String picture)
	{
		x = 0; y = 0;
		try{
			image = ImageIO.read(getClass().getResource(picture));
		} catch (Throwable e) {image = null;}
		w = image.getWidth();
		h = image.getHeight();
		setSize(w, h);
		addMouseListener(this);
		addMouseMotionListener(this);
		setContentPane(new InvisiblePanel());
	}
	
	public void paint(Graphics windowGraphics)
	{
		if(nativeImage == null || bgImage == null) {
			nativeImage = getGraphicsConfiguration().createCompatibleImage(w, h);
			windowBuffer = getGraphicsConfiguration().createCompatibleImage(w, h);
			setVisible(false);
			try{
				Thread.sleep(100);
				rob = new Robot(getGraphicsConfiguration().getDevice());
			}
			catch(Exception e) {System.exit(1);}
			bgImage = rob.createScreenCapture(new Rectangle(x, y, w, h));
			bgBuffer = rob.createScreenCapture(new Rectangle(x, y, w, h));
			setVisible(true);
		}
		Graphics g = windowBuffer.getGraphics();
		nativeImage.getGraphics().drawImage(bgImage, 0, 0, this);
		nativeImage.getGraphics().drawImage(image, 0, 0, this);
		g.drawImage(nativeImage, 0, 0, this);
		getContentPane().paint(g);
		windowGraphics.drawImage(windowBuffer, 0, 0, this);
		
	}
	public void repaint()
	{
		bgImage = null;
		super.repaint();
	}
	public void setLocation(int newX, int newY)
	{
		if(bgBuffer != null) {
			int dx = newX - x;
			int dy = newY - y;
			//first, copy background image onto iteslf displaced.
			bgBuffer.getGraphics().drawImage(bgImage, -dx, -dy, this);
			
			//second, copy new region into background...
			if(dx > 0) {
				int my = dy;
				if(my < 0) my = -my;
				Rectangle r = new Rectangle(x + w, y-my, dx, h+my*2);
				Image strip = rob.createScreenCapture(r);
				bgBuffer.getGraphics().drawImage(strip, w-dx, -dy-my, this);
			}
			else if(dx < 0) {
				int my = dy;
				if(my < 0) my = -my;
				Rectangle r = new Rectangle(x+dx, y-my, -dx, h+my*2);
				Image strip = rob.createScreenCapture(r);
				bgBuffer.getGraphics().drawImage(strip, 0, -dy-my, this);
			}
			if(dy > 0) {
				Rectangle r = new Rectangle(x, y+h, w, dy);
				Image strip = rob.createScreenCapture(r);
				bgBuffer.getGraphics().drawImage(strip, -dx, h-dy, this);
			}
			else if(dy < 0) {
				Rectangle r = new Rectangle(x, y+dy, w, -dy);
				Image strip = rob.createScreenCapture(r);
				bgBuffer.getGraphics().drawImage(strip, -dx, 0, this);
			}
			//finally, put bgBuffer back to bgImage.
			bgImage.getGraphics().drawImage(bgBuffer, 0, 0, this);
			
			this.x = newX;
			this.y = newY;
			paint(getGraphics());
		}
		super.setLocation(x, y);
		pause(1); //stops jitter
	}
	
	
	public void mousePressed(MouseEvent e){mouseX = e.getX(); mouseY = e.getY();}
	public void mouseReleased(MouseEvent e){mouseX = e.getX(); mouseY = e.getY();}
	public void mouseClicked(MouseEvent e){mouseX = e.getX(); mouseY = e.getY();}
	public void mouseEntered(MouseEvent e){mouseX = e.getX(); mouseY = e.getY();}
	public void mouseExited(MouseEvent e){mouseX = e.getX(); mouseY = e.getY();}
	
	//for dragging the window by any blank area
	public void mouseDragged(MouseEvent e){
		//first, calculate the distance moved...
		long now = System.currentTimeMillis();
		if(now - time < delay) return;
		time = now;
		
		int dx = e.getX() - mouseX;
		int dy =  e.getY() - mouseY;
		
		setLocation(x + dx, y + dy);
		mouseX = e.getX() - dx; mouseY = e.getY() - dy;
	}
	public void mouseMoved(MouseEvent e){}
	
	static void pause(long time) {
		try{ Thread.sleep(time);}
		catch(Exception e){}
	}
}
and here’s how i used it in the screenshot above:
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;
public class Demo
{
	public static void main(String[] args)
	{
		JFrame mainFrame = new BackgroundWindow("winda.png");
		mainFrame.setUndecorated(true);
		JPanel cp = (JPanel)mainFrame.getContentPane();
		cp.setLayout(null);
		
		JButton b = new JButton("Hi there!");
		b.setLocation(130,10);
		b.setSize(100,30);	
		cp.add(b);
		
		
		JTextArea text = new JTextArea("this doesnt work quite right.");
		text.setFont(new Font("Arial", Font.BOLD, 14));
		text.setForeground(Color.blue);
		text.setLineWrap(true);       //line wrapping
		text.setWrapStyleWord(true);  //wrap on end of words.
		
		JScrollPane scroll = new JScrollPane(text);
		
		scroll.setSize(300,70);
		scroll.setLocation(40, 70);
		cp.add(scroll);
		
		mainFrame.setVisible(true);
	}
}
 
      
    