站内搜索: 请输入搜索关键词
当前页面: 图书首页 > SWT: The Standard Widget Toolkit

4.3 Moving and Resizing - SWT: The Standard Widget Toolkit

Previous Section  < Day Day Up >  Next Section

4.3 Moving and Resizing

Controls are moved or resized by changing their bounds. SWT provides the following methods to set the bounds of a control.

setBounds(int x, int y, int width, int height) Sets the location and size of the control. The x and y coordinates are relative to the parent. If the width or height parameters are negative, zero is used instead.

setBounds(Rectangle bounds) Sets the location and size of the control. Equivalent to setBounds(bounds.x, bounds.y, bounds.width, bounds.height).

setLocation(int x, int y) Sets the location of the control. The x and y coordinates are relative to the parent.

setLocation(Point location) Sets the location of the control. Equivalent to setLocation(location.x, location.y).

setSize(int width, int height) Sets the size of the control. If the width or height parameters are negative, zero is used instead.

setSize(Point size) Sets the size of the control. Equivalent to setSize(size.x, size.y).

When a control is moved, an SWT.Move event is sent; when it is resized, an SWT.Resize event is sent.

4.3.1 Move Events

A control is moved when its location is changed relative to its parent (or for Shells, relative to the Display). Controls can be moved by calling setLocation(), setBounds() or, in the case of a shell, when the user repositions it on the desktop.

Table 4.1 shows the move-related events that are provided by SWT.

Table 4.1. Move Events

Untyped Event

Description

SWT.Move

The position of the control was changed

Typed Event

Listener

Methods

ControlEvent

ControlListener (and ControlAdapter)

controlMoved(ControlEvent)

controlResize(ControlEvent)


The SWT.Move event (typed event ControlEvent) is sent whenever a control is moved, after its location has been changed. It is not sent to the control when the parent or any ancestor is moved. Move events contain meaningful values in only the display, widget, and type fields.

Using SWT.Move to Make a Shell Move with Its Parent

The following example uses the SWT.Move event to implement a dialog shell that "follows the parent," moving whenever the parent is moved. The code contains a subtle problem (actually, it overlooks a case), which we will discuss further in the Resize Events section.






public static void main(String[] args) {

    //NOTE  contains a problem (see SWT.Resize)

    Display display = new Display();

    final Shell shell1 = new Shell(display);

    shell1.pack();

    shell1.open();

    final Shell shell2 = new Shell(shell1, SWT.NONE);

    shell2.pack();

    shell2.open();

    Rectangle rect = shell1.getBounds();

    shell2.setLocation(rect.x + rect.width + 2, rect.y);

    shell1.addListener(SWT.Move, new Listener() {

        public void handleEvent(Event e) {

            Rectangle rect = shell1.getBounds();

            shell2.setLocation(

                rect.x + rect.width + 2, rect.y);

        }

    });

    while (!shell1.isDisposed()) {

        if (!display.readAndDispatch()) display.sleep();

    }

    display.dispose();

}


4.3.2 Resize Events

A control is resized whenever its client area is changed. This can occur explicitly, as the result of calls to setSize() or setBounds(), or implicitly, because of some operation that the user performs. For example, the user can often resize a shell by clicking and dragging one of its corners with the mouse.[5] In addition, on some operating systems, the width of the trimmings can be changed using the "control panel" or "theme manager." For example, when a scrollbar becomes wider because the theme has changed, the client area of a control is reduced, causing the control to receive an SWT.Resize event.

[5] Provided that the shell was created with the SWT.RESIZE style and the platform window manager supports resizing.

Table 4.2 shows the resize-related events that are provided by SWT.

Table 4.2. Resize Events

Untyped Event

Description

SWT.Resize

The size of the client area of the control changed

Typed Event

Listener

Methods

ControlEvent

ControlListener (and ControlAdapter)

controlMoved(ControlEvent)

controlResized(ControlEvent)


The SWT.Resize event (typed event ControlEvent) is sent whenever a control is resized, after its size has been changed. It is not sent when the parent or any ancestor is resized. Resize events contain meaningful values in only the display, widget, and type fields.

Using SWT.Move and SWT.Size to Track a Parent Shell

The following example uses both SWT.Move and SWT.Resize events to implement a dialog shell that tracks its parent. This is a variant of the code from the previous section that adds the same listener for both SWT.Move and SWT .Resize. This fixes the problem that the previous example had: The tracking shell did not move when the user resized the bottom right corner of the parent.






public static void main(String[] args) {

    Display display = new Display();

    final Shell shell1 = new Shell(display);

    shell1.pack();

    shell1.open();

    final Shell shell2 = new Shell(shell1, SWT.NONE);

    shell2.pack();

    shell2.open();

    Rectangle rect = shell1.getBounds();

    shell2.setLocation(rect.x + rect.width + 2, rect.y);

    Listener listener = new Listener() {

        public void handleEvent(Event e) {

            Rectangle rect = shell1.getBounds();

            shell2.setLocation(

                rect.x + rect.width + 2, rect.y);

        }

    };

    shell1.addListener(SWT.Move, listener);

    shell1.addListener(SWT.Resize, listener);

    while (!shell1.isDisposed()) {

        if (!display.readAndDispatch()) display.sleep();

    }

    display.dispose();

}


Figure 4.4 shows the results of running the code. When shell1 is moved or resized, shell2 follows, remaining 2 pixels to the right.

Figure 4.4.

graphics/04fig04.gif


Using SWT.Resize to Move and Resize Children

Rather than calling setBounds(), most applications use layouts (as described in the Layout chapter) to position and resize controls. However, the SWT.Resize event is a useful alternative to layouts, allowing you precise control over the location and size of each child every time the parent is resized. You might choose to do this kind of positioning and resizing of controls inside an SWT.Resize event because you are unable to find a layout that suits your needs or because the code that is required to use the layout is simply too verbose. The alternative would be to implement a new Layout subclass that has the attributes you need, but for a single, special-purpose arrangement of widgets, this probably does not make sense.[6]

[6] The point here is that implementing a layout implies you are writing a general-purpose positioning algorithm, which is not the same as positioning a few controls in places that are specific to your application.

The following example uses an SWT.Resize event to position two buttons within a shell. The buttons are placed side by side, with an inset of 10 pixels surrounding them, as seen in Figure 4.5. When the shell is resized, the buttons grow or shrink in proportion to the new size of the shell.[7]

[7] This exact behavior can be achieved using a FillLayout with the margin and spacing set to 10 pixels. For this simple case, using a FillLayout is the easier approach.






static final int INSET = 10;

public static void main(String[] args) {

    Display display = new Display();

    final Shell shell = new Shell(display);

    final Button b1 = new Button(shell, SWT.PUSH);

    final Button b2 = new Button(shell, SWT.PUSH);

    shell.addListener(SWT.Resize, new Listener() {

        public void handleEvent(Event event) {

            Rectangle rect = shell.getClientArea();

            int width = (rect.width - INSET * 3) / 2;

            b1.setBounds(

                INSET,

                INSET,

                width,

                rect.height - INSET * 2);

            b2.setBounds(

                width + INSET * 2,

                INSET,

                width,

                rect.height - INSET * 2);

        }

    });

    shell.setSize(200, 200);

    shell.open();

    while (!shell.isDisposed()) {

        if (!display.readAndDispatch()) display.sleep();

    }

    display.dispose();

}


Figure 4.5.

graphics/04fig05.gif


    Previous Section  < Day Day Up >  Next Section