user2790209
user2790209

Reputation: 359

How to create a moveable SWT shell without title bar/ close button?

If I create a new shell using the following code:

shell = new Shell( Display.getDefault(), SWT.RESIZE);        

Then this gives me a shell without a title bar or minimize / maximize buttons, which is what I want. I'm able to resize this window to any size, which works great. But the problem is, the window is fixed in its place, and I cannot move it by dragging it around.

If I add either SWT.CASCADE or SWT.CLOSE, this gives me the title bar and close button, which I don't want, but moreover, it puts a limit on how small the window can be resized, i.e I can't resize it horizontally past a certain limit.

How can I make the window moveable without the close button / title bar? If there's no native way in SWT to do it, can I do it by listening for a mouse drag event and manually setting the location of the shell? If so, how would I get the mouse coordinates from the movement of the mouse?

Help would be appreciated. Thanks!

Upvotes: 1

Views: 3521

Answers (2)

Bibi
Bibi

Reputation: 31

This is my implementation:

/**
 * Class to allow user to move a shell without a title.
 * 
 * @author Laurent Muller
 * @version 1.0
 */
public class MoveShellListener implements Listener {

    /*
     * the parent shell
     */
    private final Shell parent;

    /*
     * the mouse down location
     */
    private Point ptMouseDown;

    /**
     * Creates a new instance of this class.
     * 
     * @param parent
     *            the shell to handle.
     */
    public MoveShellListener(final Shell parent) {
        if (parent == null) {
            SWT.error(SWT.ERROR_NULL_ARGUMENT);
        }
        if (parent.isDisposed()) {
            SWT.error(SWT.ERROR_WIDGET_DISPOSED);
        }

        // copy and add listener
        this.parent = parent;
        addControl(parent);
    }

    /**
     * Adds the given control to the list of listened controls. If the given
     * control is an instance of {@link Composite}, the children controls are
     * also added.
     * 
     * @param control
     *            the control to add.
     */
    public void addControl(final Control control) {
        // check control
        if (isDisposed(control) || control.getShell() != parent) {
            return;
        }

        // add listeners
        control.addListener(SWT.MouseDown, this);
        control.addListener(SWT.MouseUp, this);
        control.addListener(SWT.MouseMove, this);

        // children
        if (control instanceof Composite) {
            final Control[] children = ((Composite) control).getChildren();
            for (final Control child : children) {
                addControl(child);
            }
        }
    }

    /**
     * Adds the given controls to the list of listened controls. If one of the
     * given controls is an instance of {@link Composite}, the children controls
     * are also added.
     * 
     * @param controls
     *            the controls to add.
     */
    public void addControls(final Control... controls) {
        if (controls != null) {
            for (final Control control : controls) {
                addControl(control);
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void handleEvent(final Event e) {
        switch (e.type) {
        case SWT.MouseDown:
            onMouseDown(e);
            break;
        case SWT.MouseUp:
            onMouseUp(e);
            break;
        case SWT.MouseMove:
            onMouseMove(e);
            break;
        }
    }

    /**
     * Removes the given control to the list of listened controls. If the given
     * control is an instance of {@link Composite}, the children controls are
     * also removed.
     * 
     * @param control
     *            the control to remove.
     */
    public void removeControl(final Control control) {
        // check control
        if (control == parent || isDisposed(control)
                || control.getShell() != parent) {
            return;
        }

        // remove listeners
        control.removeListener(SWT.MouseDown, this);
        control.removeListener(SWT.MouseUp, this);
        control.removeListener(SWT.MouseMove, this);

        // children
        if (control instanceof Composite) {
            final Control[] children = ((Composite) control).getChildren();
            for (final Control child : children) {
                removeControl(child);
            }
        }
    }

    /**
     * Removes the given controls to the list of listened controls. If one of
     * the given controls is an instance of {@link Composite}, the children
     * controls are also removed.
     * 
     * @param controls
     *            the controls to remove.
     */
    public void removeControls(final Control... controls) {
        if (controls != null) {
            for (final Control control : controls) {
                removeControl(control);
            }
        }
    }

    /**
     * Checks if the given control is null or disposed.
     * 
     * @param control
     *            the control to verify.
     * @return true if the control is null or
     *         disposed.
     */
    private boolean isDisposed(final Control control) {
        return control == null || control.isDisposed();
    }

    /**
     * Handles the mouse down event.
     * 
     * @param e
     *            the event data.
     */
    private void onMouseDown(final Event e) {
        if (e.button == 1) {
            ptMouseDown = new Point(e.x, e.y);
        }
    }

    /**
     * Handles the mouse move event.
     * 
     * @param e
     *            the event data.
     */
    private void onMouseMove(final Event e) {
        if (ptMouseDown != null) {
            final Point location = parent.getLocation();
            location.x += e.x - ptMouseDown.x;
            location.y += e.y - ptMouseDown.y;
            parent.setLocation(location);
        }
    }

    /**
     * Handles the mouse up event.
     * 
     * @param e
     *            the event data.
     */
    private void onMouseUp(final Event e) {
        ptMouseDown = null;
    }
}

Upvotes: 3

Shishir Pandey
Shishir Pandey

Reputation: 293

You need use own listeners. Below code should help:-

public class Demo {

    static Boolean blnMouseDown=false;
    static int xPos=0;
    static int yPos=0;

    public static void main(final String[] args) {
        Display display=new Display();
        final Shell shell = new Shell( Display.getDefault(), SWT.RESIZE); 
        shell.open();

        shell.addMouseListener(new MouseListener() {

            @Override
            public void mouseUp(MouseEvent arg0) {
                // TODO Auto-generated method stub
                blnMouseDown=false;
            }

            @Override
            public void mouseDown(MouseEvent e) {
                // TODO Auto-generated method stub
                blnMouseDown=true;
                xPos=e.x;
                yPos=e.y;
            }

            @Override
            public void mouseDoubleClick(MouseEvent arg0) {
                // TODO Auto-generated method stub

            }
        });
        shell.addMouseMoveListener(new MouseMoveListener() {

            @Override
            public void mouseMove(MouseEvent e) {
                // TODO Auto-generated method stub
                if(blnMouseDown){

                    shell.setLocation(shell.getLocation().x+(e.x-xPos),shell.getLocation().y+(e.y-yPos));
                }
            }
        });

        while (!shell.isDisposed()) {
          if (!display.readAndDispatch()) {
            display.sleep();
          }
        }  
        display.close();
    }

}

Upvotes: 5

Related Questions