import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.font.TextLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;

public class TransparentWindow {

    private Window window;
    private Image staticImage;
    private BufferedImage overlay;
    private int height = 320;
    private int width = 320;
    private int wiggle = -10;
    private int paintCount = 1;

    public static void main(String[] args) {
        try {
            new TransparentWindow().start();
        } catch ( IOException ex ) {}
    }

    private void start() throws IOException {
        createStaticTransparentImage();
        displayWindow(Color.GRAY);
        displayWindow(new Color(0,0,0,0));
        System.exit(0);
    }

    private void displayWindow(Color back) {
        wiggle = -10;
        paintCount = 1;
        createDynamicTransparentImage();
        window = new MyWindow(back);
        for (int i = 0; i < 20; i++) {
            sleep(250);
            window.setSize(width + wiggle, height);
            window.repaint();
            wiggle *= -1;
        }
        sleep(2000);
        window.dispose();
    }

    private void updateWindow(Graphics2D g2D) {
        g2D.drawImage(staticImage, null, window);
        drawMessage(g2D, "Window: Hello World! " + paintCount, 40);

        Graphics2D g = overlay.createGraphics();
        g.setStroke(new BasicStroke(1f));
            /**Set Antialias Rendering**/
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
                           RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED);
        drawMessage(g, "Image: Hello World! " + paintCount, height - 40);
        g.dispose();
        g2D.drawImage(overlay, null, window);
        paintCount++;
    }

    private void drawMessage(Graphics2D g2D, String mess, int y) {
        TextLayout layout = new TextLayout(mess, g2D.getFont(), g2D.getFontRenderContext());
        int mx = (width - (int)Math.ceil(layout.getAdvance())) / 2;
        int my = y - (int)Math.ceil(layout.getDescent() + layout.getLeading());
        int mh = (int)Math.ceil(layout.getAscent() + layout.getDescent() + layout.getLeading());
        int cx = Math.max(mx - 1, 0);
        int cy = my - (int)Math.ceil(layout.getAscent()) - 1;
        int ch = mh + 2;
        int cw = (int)Math.ceil(layout.getAdvance()) + 2;
        g2D.setPaint(Color.WHITE);
        g2D.fillRect(cx, cy, cw, ch);
        g2D.setPaint(Color.BLACK);
        g2D.drawString(mess, mx, my);
    }

    private void createStaticTransparentImage() {
        staticImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = ((BufferedImage)staticImage).createGraphics();
        g.setBackground(new Color(0,0,0,0));
        g.clearRect(0, 0, width, height);
        g.setPaint(Color.CYAN);
        g.fillRect(0, 0, 80, 80);
        g.setPaint(Color.BLUE);
        g.fillRect(width - 80, 0, 80, 80);
        g.setPaint(Color.GREEN);
        g.fillRect(0, height - 80, 80, 80);
        g.setPaint(Color.MAGENTA);
        g.fillRect(width - 80, height - 80, 80, 80);
        g.setPaint(Color.YELLOW);
        g.fillOval((width / 2) - 40, (height / 2) - 40, 80, 80);
        g.dispose();
    }

    private void createDynamicTransparentImage() {
        overlay = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g = overlay.createGraphics();
        g.setBackground(new Color(0,0,0,0));
        g.clearRect(0, 0, width, height);
        g.dispose();
    }

    private void sleep(int mills) {
        try {
            Thread.sleep(mills);
        } catch ( InterruptedException ex ) {}
    }

    private class MyWindow extends Window {

        public MyWindow(Color background) {
            super(null);
            setSize(width, height);
            Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            // Center window
            int x = (screenSize.width - width) / 2;
            int y = (screenSize.height - height) / 2;
            setLocation(x, y);
            // Make Window visible
            setBackground(background);
            setAlwaysOnTop(true);
            setVisible(true);
            setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            updateWindow((Graphics2D)g);
        }

        @Override
        public void update(Graphics g) {
            paint(g);
        }

    }

}
