|
|
< Day Day Up > |
|
4.3 Moving and ResizingControls are moved or resized by changing their bounds. SWT provides the following methods to set the bounds of a control.
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 EventsA 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.
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 ParentThe 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 EventsA 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.
Table 4.2 shows the resize-related events that are provided by SWT.
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 ShellThe 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.
Using SWT.Resize to Move and Resize ChildrenRather 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]
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]
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.
| ||||||||||||||||||||||||||||||||
|
|
< Day Day Up > |
|