Sexy Swing App – The Unified Toolbar (now fully draggable)

May 3, 2008

I failed to mention in the last post that one of the critical details of making a believable Unified Toolbar is making it draggable. Anyone familar with the available Java client properties may be asking, “Why not just use apple.awt.draggableWindowBackground?”.

Unfortunately, this client property is overly aggressive and makes every component within your window draggable – hardly the desired effect. In order to create a component that is only draggable where no components exist (the empty space between components), we’ll have to implement our own class:

public class WindowDragger {

    private Window fWindow;

    private Component fComponent;

    private int dX;

    private int dY;

    public WindowDragger(Window window, Component component) {

        fWindow = window;
        fComponent = component;

        fComponent.addMouseListener(createMouseListener());
        fComponent.addMouseMotionListener(createMouseMotionListener());
    }

    private MouseListener createMouseListener() {
        return new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                Point clickPoint = new Point(e.getPoint());
                SwingUtilities.convertPointToScreen(clickPoint, fComponent);

                dX = clickPoint.x - fWindow.getX();
                dY = clickPoint.y - fWindow.getY();
            }
        };
    }

    private MouseMotionAdapter createMouseMotionListener() {
        return new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                Point dragPoint = new Point(e.getPoint());
                SwingUtilities.convertPointToScreen(dragPoint, fComponent);

                fWindow.setLocation(dragPoint.x - dX, dragPoint.y - dY);
            }
        };
    }

}

You can use this as a container anywhere you want to make the parent container draggable (including a Bottom Bar).

Drag away!

Advertisements

5 Responses to “Sexy Swing App – The Unified Toolbar (now fully draggable)”

  1. Jamison Hope Says:

    Thanks for these posts, they’re very educational.

    I have found a behavioral difference between your draggable toolbar and (the desirable part of) what you get with apple.awt.draggableWindowBackground: if you have Spaces enabled and you drag to the edge of the screen, this version just stops, whereas apple.awt.draggableWindowBackground does the expected thing and moves the window onto the next Space.

    All in all, a small price to pay for less hyperactive dragging.

  2. Ken Says:

    Hi Jamison,

    Glad you’ve found these posts useful. I’ll look into the drag issue you mentioned.

    I’ve found the apple.awt.draggableWindowBackground to be just about useless, as it lets you drag anything in the entire window in order to move it. I did bring this issue up on Java-dev (Apples Java mailing list), and Mike Swingler indicated that there were some problems with masking the window background (which indicate the draggle areas) and the Swing lightweight container hierarchy.

    -Ken

  3. Jamison Hope Says:

    I remember that thread, but that was before I started messing with TN2196 stuff so I didn’t follow it closely.

    Anyhow, it’s not just with Swing containers. If you have a JFrame with an AWT Canvas in the middle (like, say, a javax.media.j3d.Canvas3D on which you’ve installed mouse handlers to control navigation in a 3D simulation), apple.awt.draggableWindowBackground still captures the mouse motion (and thereby kills the navigation). I did find that putting the Canvas inside of a ScrollPane prevents it, but then I had a 1- or 2-pixel border around the Canvas to deal with. Your solution lets me keep behavior orthogonal to appearance.

    -Jamie

  4. Jeremy Wood Says:

    Also it’s my experience that you can add these listeners to one high-level container and all the dead space in that container becomes draggable. (Meanwhile any individual component that consumes mouse events is not affected, so the window doesn’t become ‘hyperactive’.) :)

  5. Emmanuel Says:

    Thanks for this tip :-)


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: