7.2 An SWT Example
Instead of talking about SWT in the abstract, let's
get this show on the road and see some code at work. Coding an
example is going to give us the SWT story and what it takes to put
together an SWT application. Our first example will be a simple one,
and it will just display the message "No
worries!" in an SWT window.
To follow along, create a new project, Ch07_01,
and add a class, Ch07_01, in the
org.eclipsebook.ch07 package. To work with SWT and
SWT widgets, you typically start with these two imports:
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;
You'll need to include
swt.jar in the build path to make these imports
work. Remember that SWT is operating system-dependent, so
there's going to be a different
swt.jar for different operating systems. To add
swt.jar to the Ch07_01
project, select that project in the Package Explorer, right-click it,
and select Properties. In the Properties for
Ch07_01 dialog that opens, select the Java Build
Path item and click the Add External JARs button. Then navigate to
swt.jar, which you'll find in
one of the following directories, depending on your operating system
(note that INSTALLDIR is the Eclipse
installation directory; also note that you'll have
to update these paths for your version of Eclipse, such as changing
2.1.1 to 2.1.2 or some other value):
- Win32
-
INSTALLDIR\eclipse\plugins\org.eclipse.swt.win32_2.1.1\ws\win32\swt.jar
- Linux GTK
-
INSTALLDIR/eclipse/plugins/org.eclipse.swt.gtk_2.1.1/ws/gtk/swt.jar
- Linux Motif
-
INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_2.1.1/ws/motif/swt.jar
- Solaris Motif
-
INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_2.1.1/ws/solaris/sparc/swt.jar
- AIX Motif
-
INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_2.1.1/ws/aix/ppc/swt.jar
- HPUX Motif
-
INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_2.1.1/ws/hpux/PA_RISC/swt.jar
- Photon QNX
-
INSTALLDIR/eclipse/plugins/org.eclipse.swt.photon_2.1.1/ws/photon/swt.jar
- Mac OS X
-
INSTALLDIR/eclipse/plugins/org.eclipse.swt.carbon_2.1.1/ws/carbon/swt.jar
After locating swt.jar, click Open, and then
click OK to add it to the project's build path.
|
Some operating systems, such as Linux GTK, need more than one JAR to
run SWT (in Linux GTK, you use swt.jar and
swt-pi.jar). In such cases, you have to add all
of the required JARs to the build path. (All the required JAR files
will be in the same folder.)
|
|
In the code, the next step is to create a
Display object, which represents an SWT
session. This object acts as the connection between SWT
and the operating system's GUI support. You use a
Display object to start an event loop and control
communication between the main user interface thread and other
threads. Here's how we create the
Display object in the main
method of the Ch07_01 class:
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;
public class Ch07_01 {
public static void main(String [] args) {
Display display = new Display( );
.
.
.
}
Now that you've got a
Display object, you can create the various windows
you want to work with by creating Shell objects.
In SWT, a shell is a window that is managed by the operating
system's window manager. A top-level shell is one
that is a direct child of the display and is a window the user can
move, resize, minimize, and so on. You can also have secondary
shells, which are children of another shell, such as dialogs or
message boxes. Here's how we create and size the
shell we'll be using—note that passing the
display object to the Shell
constructor makes the shell a child of the display
object:
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;
public class Ch07_01 {
public static void main(String [] args) {
Display display = new Display( );
Shell shell = new Shell(display);
shell.setSize(300, 200);
.
.
.
}
}
We're ready to add
some widgets to our application. You'll find that,
in the SWT documentation, the term widget is
used almost interchangeably with the terms
control and composite.
Technically speaking, the formal—and somewhat
circular—definition of a widget in the SWT
documentation is "the abstract class for any UI
object that can be placed inside another widget."
Practically speaking, widget is the general
term for any UI element in SWT. Composites are
widgets that are designed to have children, such as toolbars, trees,
and canvases. Controls are widgets that have an
operating system counterpart, such as buttons, lists, and labels. You
can see all the SWT controls in Table 7-1. Note
that we're also listing the possible styles and
events for each control.
Table 7-1. SWT controls and options|
Button
|
A standard push button.
|
BORDER, CHECK, PUSH, RADIO, TOGGLE, FLAT, LEFT, RIGHT, CENTER, ARROW
(with UP, DOWN)
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize, Selection
|
Canvas
|
A composite control that can contain other controls, and also is a
drawing surface. Often the foundation of custom controls.
|
BORDER, H_SCROLL, V_SCROLL, NO_BACKGROUND, NO_FOCUS, NO_MERGE_PAINTS,
NO_REDRAW_RESIZE, NO_RADIO_GROUP
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize
|
Caret
|
The standard I-beam caret used to indicate the insertion point for
text.
| |
Dispose
|
Combo
|
A standard combo box—that is, the combination of a text control
and a drop-down list.
|
BORDER, DROP_DOWN, READ_ONLY, SIMPLE
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize, DefaultSelection, Modify, Selection
|
Composite
|
Control that can contain other widgets.
|
BORDER, H_SCROLL, V_SCROLL
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize
|
CoolBar
|
A composite control that allows users to reposition contained items
dynamically.
|
BORDER
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize
|
CoolItem
|
A UI element that represents a positionable area of a cool bar.
|
DROP_DOWN
|
Dispose
|
Group
|
A composite control that groups other widgets together. Can enclose
them in an etched border and display a label.
|
BORDER, SHADOW_ETCHED_IN, SHADOW_ETCHED_OUT, SHADOW_IN, SHADOW_OUT,
SHADOW_NONE
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize
|
Label
|
The standard label control—displays text or an image.
|
BORDER, CENTER, LEFT, RIGHT, WRAP, SEPARATOR (with HORIZONTAL,
SHADOW_IN, SHADOW_OUT, SHADOW_NONE, VERTICAL)
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize
|
List
|
The standard list control—allows the user to choose items from
a list of items.
|
BORDER, H_SCROLL, V_SCROLL, SINGLE, MULTI
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize, Selection, DefaultSelection
|
Menu
|
The standard menu control—contains selectable menu items.
|
BAR, DROP_DOWN, NO_RADIO_GROUP, POP_UP
|
Dispose, Help, Hide, Show
|
MenuItem
|
UI object that represents an item in a menu.
|
CHECK, CASCADE, PUSH, RADIO, SEPARATOR
|
Dispose, Arm, Help, Selection
|
ProgressBar
|
The standard progress bar—displays progress of a task to the
user, usually as a bar graph.
|
BORDER, INDETERMINATE, SMOOTH, HORIZONTAL, VERTICAL
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize
|
Sash
|
Allows the user to drag a
"rubber-banded" outline of the sash
within the parent window to allow users to resize child widgets by
moving their dividing lines.
|
BORDER, HORIZONTAL, VERTICAL
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize, Selection
|
Scale
|
Control that represents a range of numeric values.
|
BORDER, HORIZONTAL, VERTICAL
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize, Selection
|
ScrollBar
|
The standard scrollbar—represents a range of positive numeric
values.
|
HORIZONTAL, VERTICAL
|
Dispose, Selection
|
Shell
|
A window that is managed by the operating system window manager.
|
BORDER, H_SCROLL, V_SCROLL, CLOSE, MIN, MAX, NO_TRIM, RESIZE, TITLE
(see also SHELL_TRIM,DIALOG_TRIM)
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize, Activate, Close, Deactivate,Deiconify, Iconify
|
Slider
|
Control that represents a range of numeric values, which the user can
select by positioning a draggable thumb.
|
BORDER, HORIZONTAL, VERTICAL
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize, Selection
|
TabFolder
|
Composite control that groups controls into pages that the user can
select using labeled tabs.
|
BORDER
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize, Selection
|
TabItem
|
Control corresponding to a tab in a tab folder.
| |
Dispose
|
Table
|
Control that displays a list of table items.
|
BORDER, H_SCROLL, V_SCROLL, SINGLE, MULTI, CHECK, FULL_SELECTION,
HIDE_SELECTION
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize, Selection, DefaultSelection
|
TableColumn
|
UI object that represents a column in a table.
|
LEFT, RIGHT, CENTER
|
Dispose, Move, Resize, Selection
|
TableItem
|
UI object that represents an item in a table.
| |
Dispose
|
Text
|
The standard text control, which allows the user to type text into it.
|
BORDER, SINGLE, READ_ONLY, LEFT, CENTER, RIGHT, WRAP, MULTI (with
H_SCROLL, V_SCROLL)
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize, DefaultSelection, Modify, Verify
|
ToolBar
|
The standard toolbar—a composite control that contains toolbar
items.
|
BORDER, FLAT, WRAP, RIGHT, SHADOW_OUT HORIZONTAL, VERTICAL
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize
|
ToolItem
|
UI object that represents an item in a toolbar.
|
PUSH, CHECK, RADIO, SEPARATOR, DROP_DOWN
|
Dispose, Selection
|
Tracker
|
UI object that implements
"rubber-banding" rectangles.
|
LEFT, RIGHT, UP, DOWN, RESIZE
|
Dispose, Move, Resize
|
Tree
|
Control that displays a hierarchical list of tree items.
|
BORDER, H_SCROLL, V_SCROLL, SINGLE, MULTI, CHECK
|
Dispose, FocusIn, FocusOut, Help, KeyDown, KeyUp, MouseDoubleClick,
MouseDown, MouseEnter, MouseExit, MouseHover, MouseUp, MouseMove,
Move, Paint, Resize, Selection, DefaultSelection, Collapse, Expand
|
TreeItem
|
UI object that represents a tree item in a tree.
| |
Dispose
|
In this example, we're going
to use an SWT label to display our "No
worries!" message. You can see the possible styles
for labels and all SWT controls in Table 7-1; here
are more details for the label styles:
- SWT.BORDER
-
Adds a border
- SWT.CENTER
-
Centers text
- SWT.LEFT
-
Left-justifies text
- SWT.RIGHT
-
Right-justifies text
- SWT.WRAP
-
Wraps text
- SWT.SEPARATOR
-
Supports a separator
Here's how we create a label and set its text as
appropriate—note that we're centering the
label by setting its style to SWT.CENTER and
setting the bounds of the label to correspond to the entire client
area of the shell:
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;
public class Ch07_01 {
public static void main(String [] args) {
Display display = new Display( );
Shell shell = new Shell(display);
shell.setSize(300, 200);
Label label = new Label(shell, SWT.CENTER);
label.setText("No worries!");
label.setBounds(shell.getClientArea( ));
.
.
.
}
Finally, you open the shell to display it
and add the event-dispatching loop. That loop usually keeps going
until the user closes the main window. In the body of the loop, we
check if the display object needs to dispatch a
message, and then make that object sleep for a while. After the loop
terminates, we dispose of the display object, as
you can see in the final listing for Example 7-1.
Example 7-1. The first SWT application, Ch07_01.java
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;
public class Ch07_01 {
public static void main(String [] args) {
Display display = new Display( );
Shell shell = new Shell(display);
shell.setSize(300, 200);
Label label = new Label(shell, SWT.CENTER);
label.setText("No worries!");
label.setBounds(shell.getClientArea( ));
shell.open( );
while(!shell.isDisposed( )) {
if(!display.readAndDispatch( )) display.sleep( );
}
display.dispose( );
}
}
Note, in particular, that when
we're done with the display
object, we dispose of it with its dispose method.
Disposing of resources like this is not necessary in AWT or Swing,
but it is in SWT because the operating systems under SWT require the
explicit allocation and disposing of resources. The upshot is that
SWT requires you to free any operating system resources that you have
allocated, and you can use the
widget.dispose method
to do that.
That completes the code, but
this example is not yet ready to run; the next step is to add the
native code support JNI library in the path so the Java virtual
machine can find that native code. Recall that SWT uses native code
support for display, which means that you had to use some JNI code.
To do that, select the class that you want to run
(Ch07_01 here) in the Package Explorer, and select
Run Run to set up a launch configuration.
In the Launch Configurations dialog that
appears, select Java Application and click the New button. The Name,
Project, and Main class boxes should be filled in; if
they're not, fill them in now. Then click the
Arguments tab, and in the VM Arguments box, insert the location of
the SWT library, which depends on your operating system
(you'll have to update these paths for your version
of Eclipse, such as changing 2.1.1 to 2.1.2 or something similar):
- Win32
-
-Djava.library.path=INSTALLDIR\plugins\org.eclipse.swt.win32_2.1.1\os\win32\x86
- Linux GTK
-
-Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.gtk_2.1.1/os/linux/x86
- Linux Motif
-
-Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_2.1.1/os/linux/x86
- Solaris Motif
-
-Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_2.1.1/os/solaris/sparc
- AIX Motif
-
-Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_2.1.1/os/aix/ppc
- HPUX Motif
-
-Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_2.1.1/os/hpux/PA_RISC
- Photon QNX
-
-Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.photon_2.1.1/os/qnx/x86
- Mac OS X
-
-Djava.library.path=INSTALLDIR/eclipse/plugins/org.eclipse.swt.carbon_2.1.1/os/macosx/ppc
Then click the Apply button, followed by the Run button. You should
see this new example at work, as in Figure 7-1.
That's our first SWT application—not too
involved, but now we've got the basics of SWT
applications down.
|