ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button O'Reilly Book Excerpts: Swing Hacks

Hacking Swing: Translucent Windows

by Joshua Marinacci and Chris Adamson

Editor's note: The following example from Swing Hacks is one of the book's most visually daring hacks--mimicking the arbitrarily shaped window you might see in an native MP3 player skin. The hack here is necessitated by the fact that Java doesn't support non-rectangular windows, so the only option to make this work is for the Java window to be aware of what's under it, and to handle the imaging of areas within the window's rectangle but not within its arbitrary shape. Read on for how this is accomplished.

figureHack 41

Create translucent and shaped windows, while avoiding native code, with clever use of a screenshot.

One of the most commonly requested Swing features is transparent windows. Also called shaped windows, these are windows that have transparent portions, allowing the desktop background and other programs to shine through. Java doesn't provide any way of creating transparent windows without using the Java Native Interface (JNI) (and even then the native platform must support transparency as well), but that's not going to stop us. We can cheat using one of my favorite techniques, the screenshot.

The process of faking a transparent window is basically:

  1. Take a screenshot before the window is shown.

  2. Use that screenshot as the background of the window.

  3. Adjust the position so that the screenshot and the real screen line up, creating the illusion of transparency.

This is the easy part. The hard part is updating the screenshot when the window moves or changes.

To start off, create a JPanel subclass that can capture the screen and paint it as the background, as shown in Example 6-1.

Example 6-1. A transparent background component

public class TransparentBackground extends Jcomponent { 
    private JFrame frame; 
    private Image background;

public TransparentBackground(JFrame frame) {
    this.frame = frame;
    updateBackground( );
}

public void updateBackground( ) {
    try {
        Robot rbt = new Robot( );
        Toolkit tk = Toolkit.getDefaultToolkit( );
        Dimension dim = tk.getScreenSize( );
        background = rbt.createScreenCapture(
        new Rectangle(0,0,(int)dim.getWidth( ),
                          (int)dim.getHeight( )));
    } catch (Exception ex) {
        p(ex.toString( ));
        ex.printStackTrace( );
    }
}
public void paintComponent(Graphics g) {
    Point pos = this.getLocationOnScreen( );
    Point offset = new Point(-pos.x,-pos.y);
    g.drawImage(background,offset.x,offset.y,null);
}
}

First, the constructor saves a reference to the parent JFrame; then it calls updateBackground( ), which captures the entire screen using java.awt.Robot. createScreenCapture( ), and saves the capture in the background variable. paintComponent( ) gets the panel's absolute position on screen and then fills the panel with the background image, shifted to account for the panel's location. This makes the fake background image line up with the real background, giving the appearance of transparency.

You can run this with a simple main( ) method, dropping a few components onto the panel and putting it into a frame:

public static void main(String[] args) {
    JFrame frame = new JFrame("Transparent Window");
    TransparentBackground bg = new TransparentBackground(frame);
    bg.setLayout(new BorderLayout( ));
    JButton button = new JButton("This is a button");
    bg.add("North",button);
JLabel label = new JLabel("This is a label");
    bg.add("South",label);
    frame.getContentPane( ).add("Center",bg);
    frame.pack( );
    frame.setSize(150,100);
    frame.show( );
}

The code produces a window that looks like Figure 6-1.

Figure 6-1
Figure 6-1. Transparent windows in action

Swing Hacks

Related Reading

Swing Hacks
Tips and Tools for Killer GUIs
By Joshua Marinacci, Chris Adamson

Pages: 1, 2, 3

Next Pagearrow