Ой! Заметка есть, а русский букв нет. Обещаю, описание будет, но позже :)

AnyFrame.java

package ru.jcup.education.graphics.swing.anyshape;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import ru.jcup.education.graphics.java2d.utils.LoadImage;

import com.sun.awt.AWTUtilities;

public class AnyFrame extends JFrame implements MouseListener, MouseMotionListener {

	private static final long serialVersionUID = 1L;
	private BufferedImage image;

	AnyFrame() {
		this.setUndecorated(true);

		String imagePath = "/ru/jcup/education/graphics/resource/png/cloud.png";
		
		image = LoadImage.loadBufferedImage(imagePath);
		this.setSize(image.getWidth(), image.getHeight());
		
		Shape frameShape = ShapeUtils.prepareShape(imagePath, image);
		
		AWTUtilities.setWindowShape(this, frameShape);
		AWTUtilities.setWindowOpacity(this, 0.90f);
		AWTUtilities.setWindowOpaque(this, false);
		
		centerScreen(this);
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
		this.setVisible(true);
	}

	
	@Override
	public void paint(Graphics g) {
		g.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
	}

	private void centerScreen(JFrame frame) {
		Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
		int w = frame.getSize().width;
		int h = frame.getSize().height;
		int x = (dim.width - w) / 2;
		int y = (dim.height - h) / 2;
		frame.setLocation(x, y);
	}

	private Point start_drag;
	private Point start_loc;

	@Override
	public void mouseDragged(MouseEvent e) {
		final Point current = this.getScreenLocation(e);
		SwingUtilities.getRoot(this).setLocation(
				new Point(this.start_loc.x + current.x - this.start_drag.x,
						this.start_loc.y + current.y - this.start_drag.y));
	}

	@Override
	public void mouseMoved(MouseEvent arg0) {
	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
	}

	@Override
	public void mousePressed(MouseEvent e) {
	    this.start_drag = this.getScreenLocation(e);
	    this.start_loc = SwingUtilities.getRoot(this).getLocation();
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
	}

	private Point getScreenLocation(final MouseEvent e) {
		final Point cursor = e.getPoint();
		final Point target_location = this.getLocationOnScreen();
		return new Point(target_location.x + cursor.x, target_location.y + cursor.y);
	}

}

ShapeUtils.java

package ru.jcup.education.graphics.swing.anyshape;

import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.image.BufferedImage;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * This code get from http://habrahabr.ru/post/127240/
 * Method prepareShape write by Saa.
 * This code provide an opportunity automated create shape file at first load.
 */
public class ShapeUtils {

	public static Shape contour(final BufferedImage i) {
		final int w = i.getWidth();
		final int h = i.getHeight();
		final Area s = new Area(new Rectangle(w, h));
		final Rectangle r = new Rectangle(0, 0, 1, 1);
		for (r.y = 0; r.y < h; r.y++) {
			// System.out.println(r.y + "/" + h);
			for (r.x = 0; r.x < w; r.x++) {
				if ((i.getRGB(r.x, r.y) & 0xFF000000) != 0xFF000000) {
					s.subtract(new Area(r));
				}
			}
		}
		return s;
	}
	
	public static void save(final Shape s, final DataOutput os) throws IOException {
		final PathIterator pi = s.getPathIterator(null);
		os.writeInt(pi.getWindingRule());
		System.out.println(pi.getWindingRule());
		while (!pi.isDone()) {
			final double[] coords = new double[6];
			final int type = pi.currentSegment(coords);
			os.writeInt(type);
			for (final double coord : coords) {
				os.writeDouble(coord);
			}
			pi.next();
		}
	}

	public static Shape load(final DataInput is) throws IOException {
		final GeneralPath gp = new GeneralPath(is.readInt());
		final double[] data = new double[6];
		CYC: while (true) {
			final int type = is.readInt();
			for (int i = 0; i < data.length; i++) {
				data[i] = is.readDouble();
			}
			switch (type) {
			case PathIterator.SEG_MOVETO:
				gp.moveTo(data[0], data[1]);
				break;
			case PathIterator.SEG_LINETO:
				gp.lineTo(data[0], data[1]);
				break;
			case PathIterator.SEG_QUADTO:
				gp.quadTo(data[0], data[1], data[2], data[3]);
				break;
			case PathIterator.SEG_CUBICTO:
				gp.curveTo(data[0], data[1], data[2], data[3], data[4], data[5]);
				break;
			case PathIterator.SEG_CLOSE:
				break CYC;
			}
		}
		return gp.createTransformedShape(null);
	}
	
	public static Shape prepareShape(String imageFile, BufferedImage image) {
		String shapeFile = imageFile.substring(0, imageFile.lastIndexOf(".")) + ".shp";
		String imageFileFull = System.getProperty("user.dir") + File.separator + "src" + shapeFile;

		File file = new File(imageFileFull);
		if (!file.exists()) {
			System.out.println("Компилирую изображение в форму.");
			System.out.println(imageFileFull);
			Shape shapeImage = ShapeUtils.contour(image);
			try {
				DataOutput dataOuput = new RandomAccessFile(file, "rw");
				ShapeUtils.save(shapeImage, dataOuput);
			} catch (IOException e) {
				e.printStackTrace();
			}
			return shapeImage;
		} else {
			Shape shapeImage = null;
			//System.out.println("Загружаю форму изображения.");
			DataInput dataInput;
			try {
				dataInput = new RandomAccessFile(file, "r");
				shapeImage = ShapeUtils.load(dataInput);
			} catch (IOException e) {
				e.printStackTrace();
			}
			return shapeImage;
		}
	}

}