SWT Tutorial (Java)
SWT Tutorial (Java)
SWT Tutorial
Patrick Salamin
supervised by
Paul-Louis Meylan
Prof. Claude Petitpierre
at the
1 Why SWT? 9
3 Environment set-up 13
6 SWT packages 21
7 Dialogs 23
7.1 MessageBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
7.2 ColorDialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
7.3 DirectoryDialog . . . . . . . . . . . . . . . . . . . . . . . . . . 30
7.4 FontDialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
7.5 FileDialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
7.6 PrintDialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
8 Widgets 39
8.1 Widget Events . . . . . . . . . . . . . . . . . . . . . . . . . . 40
8.1.1 How to use the listeners (SelectionListener) . . . . . . 41
8.1.2 KeyListener . . . . . . . . . . . . . . . . . . . . . . . . 42
8.1.3 MouseListener . . . . . . . . . . . . . . . . . . . . . . . 44
MouseListener . . . . . . . . . . . . . . . . . . . . . . . 44
MouseMoveListener . . . . . . . . . . . . . . . . . . . . 45
MouseTrackListener . . . . . . . . . . . . . . . . . . . 46
8.1.4 TextListener . . . . . . . . . . . . . . . . . . . . . . . . 46
ModifyListener . . . . . . . . . . . . . . . . . . . . . . 46
VerifyListener . . . . . . . . . . . . . . . . . . . . . . . 46
8.1.5 FocusListeners and TraverseListener . . . . . . . . . . 47
3
CONTENTS
FocusListener . . . . . . . . . . . . . . . . . . . . . . . 47
TraverseListener . . . . . . . . . . . . . . . . . . . . . 47
8.2 Useful widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
8.2.1 Buttons . . . . . . . . . . . . . . . . . . . . . . . . . . 49
8.2.2 Slider, Scale and ProgressBar widgets . . . . . . . . . . 51
Slider and Scale . . . . . . . . . . . . . . . . . . . . . . 51
ProgressBar . . . . . . . . . . . . . . . . . . . . . . . . 53
8.2.3 Text widget . . . . . . . . . . . . . . . . . . . . . . . . 54
8.2.4 List widget . . . . . . . . . . . . . . . . . . . . . . . . 56
8.3 Composite widgets . . . . . . . . . . . . . . . . . . . . . . . . 58
8.3.1 Table widget . . . . . . . . . . . . . . . . . . . . . . . 60
TableColumn . . . . . . . . . . . . . . . . . . . . . . . 61
TableItem . . . . . . . . . . . . . . . . . . . . . . . . . 61
8.3.2 Combo widget . . . . . . . . . . . . . . . . . . . . . . . 65
8.3.3 Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
8.3.4 TabFolder . . . . . . . . . . . . . . . . . . . . . . . . . 70
8.3.5 CoolBar . . . . . . . . . . . . . . . . . . . . . . . . . . 72
8.4 Menu Widgets . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
8.4.1 Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Simple Menu . . . . . . . . . . . . . . . . . . . . . . . 76
Advanced Menu . . . . . . . . . . . . . . . . . . . . . . 78
8.4.2 Pop-Up Menu . . . . . . . . . . . . . . . . . . . . . . . 82
8.5 A summary of controls having items . . . . . . . . . . . . . . . 85
9 Layouts 87
9.1 FillLayout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
9.2 RowLayout . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
9.3 GridLayout . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
9.4 FormLayout . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
9.5 StackLayout . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
5
LIST OF FIGURES
Why SWT?
First of all, let us just talk about what is SWT ? It is a cross platform GUI
developed by IBM. But why did IBM create another GUI library ? Why
do not they have used the already existing Java GUI frameworks ? Let us
return a little in the past of the Java history...
At first, Sun created a cross platform GUI framework AWT (Abstract Win-
dowing Toolkit). This toolkit uses native widgets but it suffers from an LCD
problem which causes loss of major platform features. More concretely, if
a platform (P1) tolerate the widgets 1 to 40 and an other platform (P2)
tolerate the widgets 20 to 25, then the cross-platform AWT framework only
offers the intersection of these two sets.
In order to solve this problem, Sun created a new framework that uses em-
ulated widgets instead of native widgets: Swing. This approach solved the
LCD problem and provided a rich set of widgets but created other problems.
For instance, Swing applications no longer look like the native applications.
Although they are the latest improvements in the JVM, the Swing applica-
tions suffer performance problems that do not exist in their native counter-
parts. Moreover, the Swing applications consume too much memory, which
is not suitable for small devices such as PDAs and Mobile Phones.
IBM decided that no one of these approaches fulfill their requirements. So,
IBM created a new GUI library, called SWT (Standard Widget Toolkit),
which solves the problems seen with the AWT and the Swing frameworks.
The SWT framework accesses native widgets through JNI (Java Native In-
terface). If a widget is not available on the host platform, SWT emulates
it.
9
Semester project, 2004 10 SWT Tutorial
Chapter 2
The Display, Shell, and Widgets elements are the basic building blocks in an
SWT application. The Display instance is responsible from managing event
loops and controlling communication between the UI thread and the other
threads and the Shell instance corresponds to the window in an application
managed by the OS window manager. In an SWT application one Display
and one or more Shell instances are needed at least. The Widget instances
are elements we will put on the window (we will describe them and their use
in the chapter 8).
11
• The diagram on the left is the simplified inheritance diagram of the UI
objects
Each thread of an application (they can be several) uses its own instance
of a Display object. The current active instance of a Display object can be
obtained by using the static Display.getCurent() method. The Shell ob-
ject represents a window in a particular operating system. It can be normal,
maximized or minimized. There are two types of Shell s:
Shell type depends on the style bit constant(s) passed to the Shell construc-
tor. If a Display object is given to the parameter, it is a top-level shell,
otherwise the default value of a Shell is DialogShell.
Some widget properties must be set at the creation time. These widget
properties are called style bits. They are defined as constants in the SWT
class, e.g. Button button = new Button (shell, <style bit(s)>). It is
possible to use more than one style bit by using the OR operator (|). For
instance, to use a bordered ”push button”, you need to use SWT.PUSH |
SWT.BORDER in the style bit parameters.
Environment set-up
13
To set the java.library.path variable, go to Run -> Run... -> Java
Application -> New -> Arguments -> VM Arguments. Thereafter, if neces-
sary, modify the path below and paste it to the VM Arguments field.
-Djava.library.path=ECLIPSE HOME\eclipse\plugins\
org.eclipse.swt.win32 3.1.0\os\win32\x86 If you need to load any na-
tive library that your application uses, you can use the method:
Runtime.getPlatform.loadLibrary(LIBRARY NAME)
After these steps you will be able to run an SWT application within your
eclipse environment.
• Create Widget(s) inside the Shell (s) (as many as you want)
You can use the following code template to quickly run the code parts given
later in this tutorial.
15
Figure 4.1: The simplest SWT application source code
This example displays an empty window in which you can add your wid-
gets to the template above. As said before, every SWT application requires
(1)a Display and one or more (2)Shell s. The Shell is a Composite object:
it can contain other Composite objects. If the (3)Layout of the Shell is not
set, added widgets to the Shell will not be visible. You can (4) set the size
and the title of your window. The Shell window must be (5)opened to be
(6)displayed. The event handling loop reads and dispatches the GUI Events.
If there is no event handling loop, the application window cannot be shown,
even if the Shell window is opened by the open() method. Afterwards, you
should dispose the (7)Display, when the Shell is discarded.
The result of this code can be seen here:
Figure 4.2: Simplest SWT application resulting from the preceding code
You can use the Source -> Organize Imports menu or Ctrl+Shift+O to au-
tomatically import the required libraries.
Then you will only have to put the following lines in your terminal to compile
and launch your application:
>javac MyClass.java
>java MyClass
19
The SWT libraries are available under the Eclipse plug-in directory. If
you want to get the SWT libraries without downloading the whole Eclipse
package, it is possible to download a single SWT library or the eclipse envi-
ronment by clicking on the following link:
http://www.eclipse.org/downloads/index.php
Note that if it does not work with the preceding instructions, you can try
the following actions (a bit more complex):
SWT packages
org.eclipse.swt
Contains classes that define constants and exceptions used by the SWT
classes. It consists of three classes: SWT, SWTException and, SWTError. The
SWT will probably be your favorite class because it contains constants for
SWT libraries such as keyboard, error, color, layout, text style, button,...
and the style bit constants.
org.eclipse.swt.widgets
Contains most of the SWT widget components, including the support inter-
face and classes. We will speak about them from the section 8.2.
org.eclipse.swt.events
Defines listeners and (typed) events, that SWT components use. This pack-
age contains three different groups of classes: the Listener interfaces, the
Adapter and Event classes. We will speak about them in the section 8.1
org.eclipse.swt.layout
Contains classes providing predefined positioning and sizing of the SWT wid-
gets.
21
org.eclipse.swt.print
Contains classes providing print support for the SWT widgets.
org.eclipse.swt.graphics
Provides the classes concerning points, rectangles, regions, colors, cursors,
fonts, graphics contexts (that is, GCs) where most of the primitive drawing
operations are implemented, and images including both the code for display-
ing them and the public API for loading/saving them.
Dialogs
23
There exist different types of dialogs: they can have specific properties
(as shown here).
Each Dialog open() method returns a different type:
• The MessageBox dialog returns an int from the open() method. There-
fore, one must write different conditions to handle the return value for
each Dialog. We will speak about them in the section 7.1.
• The FontDialog, which enables a user to select a font from all avail-
able fonts in the system, returns a FontData object from the open()
method. We will speak about them in the section 7.4
• The FileDialog enables a user to select a file. Additionally, you can set
an extension filter, path filter, and filename filters. This dialog has the
following style bit constants: SWT.OPEN to show the Open button on
the dialog and SWT.SAVE to show the Save button on the dialog.
The following table shows a list of available icons for the dialogs
Figure 7.3: Most important style bit constants for the Dialogs for the icons
7.1 MessageBox
The MessageBox is really useful to inform or warn the user or to get a basic
response from the user. It can display a message with an icon to the user
and provide buttons to allow the user to respond to the system.
To add a MessageBox that asks the user something and gives him possible
replies of ”Yes”, ”No” or ”Cancel”, you can use the following code (the last
part of this code will serve to treat the user’s answer):
As said before, the open() method of the MessageBox class will return
an int representing the response from the user.
The different icon styles were given in the figure 7.4 and the possible styles
for the types of responses are: SWT.OK, SWT.CANCEL, SWT.YES, SWT.NO,
SWT.RETRY, SWT.ABORT, SWT.IGNORE
7.2 ColorDialog
The ColorDialog allows users to select a color from a predefined set of avail-
able colors in a palette. To add a color dialog to your Shell, you can use
the following code (the last part of this code will serve to treat the user’s
answer):
As said before, the open() method of the ColorDialog class will return
an object of type RGB representing the color the user selected. It will return
null if the dialog was cancelled, if no color was selected or if an error occurred.
7.3 DirectoryDialog
The DirectoryDialog allows the user to navigate through the file system of
his computer (or network) and select a directory. To add a DirectoryDialog
to your Shell, you can use the following code (the last part of this code will
serve to treat the user’s answer):
As said before, the open() method of the DirectoryDialog class will return
a string describing the absolute path of the selected directory, or null if the
dialog was cancelled or if an error occurred.
7.4 FontDialog
The FontDialog allows the user to select a font in all the available fonts in
his system. To add a FontDialog to your Shell, you can use the following
code (the last part of this code will serve to treat the user’s answer):
As said before, the open() method of the FontDialog class will return a
FontData object describing the font that was selected, or null if the dialog
was cancelled or an error occurred.
7.5 FileDialog
The FileDialog allows a user to navigate through the file system and select or
enter a file name. To add a FileDialog to your shell you can use the following
code (the last part of this code will serve to treat the user’s answer):
As said before, the open() method of the FileDialog class will return a
String describing the absolute path of the first selected file, or null if the
dialog was cancelled or an error occurred.
The possible styles of the FileDialog are SWT.OPEN, SWT.SAVE and SWT.MULTI
7.6 PrintDialog
The PrintDialog allows the user to select a printer and various print-related
parameters prior to starting a print job. To add a PrintDialog to your Shell
you can use the following code (the last part of this code will ser to treat the
user’s answer):
As said before, the open() method of the PrintDialog class will return a
PrinterData object containing all the information the user selected from the
dialog. If the dialog was cancelled or an error occurred, the open() method
will return null.
Note that the PrintDialog class contains the following methods: getEndPage(),
getPrintToFile(), getScope() and getStartPage() which return their
respective fields the user selected before pressing OK or Cancel in the dialog.
It is not recommended to use these methods to determine information for a
print job as they return values even if the user cancelled the dialog.
Widgets
Note that the Widget, Item, ScrollBar and Control classes are abstract
classes.
39
8.1. WIDGET EVENTS
1. First, you will have to create a listener which is specific to the event
that you wish to capture. There is an interface for each listener that
you can use: SelectionListener and a class that will provide you with
the event informations: SelectionEvent. Within the listener that you
created, you will have to implement the methods that are predefined
in the interface (which appears automatically when you create a new
object of this type if you use Eclipse).
When it only requires to implement one method, you can create and
use an adapter instead of a listener: SelectionAdapter. The adapter
implements the interface with empty methods so that you do not have
to write some code for methods that you do not need in your listener.
Note that in our SelectionListener, we did not add any code for the
widgetDefaultSelected() method. So we simply could have used an
adapter, and only implement the widgetSelected() method.
2. The second thing is that you will have to add the listener to your
widget. For this, you will see that each control has methods to add
listeners: addSelectionListener(). Then you pass your listener as
argument to this method, and you are ready to capture events.
Now that we have seen how to create, add and use a listener to a widget, let
us have a look at the most often used types of listeners.
8.1.2 KeyListener
The KeyListener object has two methods: keyPressed() and keyReleased(),
whose functions are obvious. The event object is of KeyEvent type and be-
cause there are only two methods, a KeyAdapter can also be used to imple-
ment only one of these methods.
The KeyEvent is the most interesting feature to capture keyboard events.
It has a property called character that stores which character was just
pressed. You can access this character value using e.character (where e is
a KeyEvent instance). You can also access the key code and state mask of
the pressed key. The key codes are for special keys and are constants in the
SWT library, like SWT.CTRL for the control key and SWT.CR for the carriage
return key and the state mask indicates the status of the keyboard modifier
keys.
The following example shows how to use the keyPressed() and keyReleased()
methods. At first, we attach a KeyListener to a basic widget (e.g. a
Text)and a KeyEvent is generated every time you type in the text. With
the keyPressed() method, we check if the pressed key was a special key
(such as tab, carriage return, etc.), and print out the readable character for
that key. Otherwise, we print out the character as is. In the keyReleased()
method, we check if the control key was pressed before another character was
pressed, such as Control-C. This is a method that could be used to capture
ctrl-key sequences in a widget such as a text:
8.1.3 MouseListener
There are three kinds of MouseListener :
We will go over all these three listeners. But since we are dealing with events,
it is not possible to show the results.
MouseListener
The MouseListener has three methods, mouseDown(), mouseUp() and the
mouseDoubleClick() (obvious functions). Once again a MouseAdapter is
available and MouseEvent is the class that contains information on the event.
The MouseEvent fields are x, y, stateMask and button. This last property
returns the number of the button that was pressed or released: a value of
1 for the first button on the shell, 2 for the the second,... The x and y
properties return the mouse coordinates at the moment of the event and the
stateMask property returns the state of the keyboard modifier keys at the
event time.
In the following example there are two MouseAdapter s:
Note that if you press on the first button, it tells you that Button 1 has
been pressed, and pressing on the second button tells you that Button 2 has
been pressed. If you press your mouse down, move it around, and then release
it, anywhere else you will see the different coordinates where your mouse was
pressed and released at.
MouseMoveListener
There is only one method for the MouseMoveListener : mouseMove(). This
method is invoked when the mouse is moved over the control onto which
the listener is attached. As usual, MouseEvent is the type of the generated
event.
MouseTrackListener
The MouseTrackListener has three methods: mouseEnter() that is called
when the mouse enters into the area covered by the Control to which it is
attached, mouseExit() that is called when the mouse exits the area covered
by the Control to which it is attached and mouseHover that is called when
the mouse hovers over the area covered by the Control to which it is attached.
8.1.4 TextListener
There are a couple of listeners that are very useful when you use the Text
widgets: ModifyListener which is called when text is modified and VerifyLis-
tener which is called before text is modified. The last one can be used to
verify that the new entered values are valid. We will briefly go over both of
these listeners.
ModifyListener
The ModifyListener has one method, modifyText() whose produced event
is a ModifyEvent (similar to TypedEvent, and has a time and a widget fields.
It can be used when we need to be notified if the text has been changed. The
modifyText() method is called every time a character is modified (add or
erased). You can see an example of its used in the end of the VerifyListener
subsection.
VerifyListener
The only method of the VerifyListener is verifyText() and its event is of
type VerifyEvent. This event has all the properties of a TypedEvent and a
KeyEvent, as well as the fields: start that indicate the range of text which
is about to be modified, end that indicate the range of text which is about
to be modified, doit that indicates whether or not we should complete the
action that triggered the event and text that indicates the new text to which
your text is being changed.
We can use this listener to be sure that a field can be filled by some specific
characters. In the following example, we check if the user is entering an
asterisk (*)in the Text widget and if it is the case the action is cancelled.
(Notice that it does not matter how many times the ”*” key is pressed... no
asterisk will never appear in the widget.
FocusListener
The FocusListener has two methods: focusGained() and focusLost() whose
functions seem to be obvious. The generated event is of type FocusEvent and
has all the properties of a TypedEvent. The example in the TraverseListener
paragraph will give you more details.
TraverseListener
The only method of the TraverseListener is keyTraversed(). It is called
when the widget to which the handler is attached is traversed by a traversal
method (e.g. ”tabs”, ”up arrow”, ”down arrows”,...).
The generated event is the TraverseEvent whose the most useful properties
are: detail that indicates what kind of traversal generated the event and
doit that is the same as for the VerifyListener (it sets a flag indicating
whether the event should continue).
All these traversals can be referred to by using the SWT.TRAVERSE XXX style
You always need to specify at least a style bit constant for every one of them
(even SWT.NONE if you do not know which constant to use or if you do not
want to specify anyone.
8.2.1 Buttons
A Button is a widget the user can click onto in order to start an action. To
place a Button on the Shell, you can use the following code:
A Button can have different styles that depend on its defined style bit con-
stant(s). A list of Button objects and their style constants is shown in table
on the following page.
A basic event handler for the button is a selection event handler which
is called when the button is selected by clicking on it. To create the event
handler, we add a listener to the button using the preceding code as seen in
the section 8.1.1
Figure 8.16: Scale and Slider resulting from the previous code
We can change the orientation of the Scale and Slider widgets depend-
ing on the style bist constants we use in the constructor(SWT.VERTICAL or
SWT.HORIZONTAL).
Optionally, you can use the SWT.BORDER constant to create a border around
the Scale widget, but this will not have any effect on the Slider widget.
ProgressBar
The main difference between the ProgressBar widgets and the Slider and
Scale widgets is that you cannot select it. It usually shows the progress
of a task and its principle style bit constants are: SWT.HORIZONTAL and
SWT.VERTICAL for the orientation, SWT.SMOOTH that makes a continue progress
line and SWT.INDETERMINATE that makes the progress line always get bigger
– as for some downloads under the Windows OS.
Here is a simple code example and its result:
The commented code on the following page shows how to create the three
specific kind of Text widgets appearing in the next window:
This is the code that is necessary to get the result on the following page:
Note that list2 must be declared as final in order to use it within the adapter.
The Composite classes can usually contain other composite classes. This con-
tainment is built up by using the constructor of a Composite widget class.
But in contrary to the Swing GUI, there is not an add() method. So you
must use their constructors to build up a containment structure.
As you can see in the previous figure, the Shell class is also a Composite
class. This means that the Shell object can contain other Composite classes.
The Composite widgets are Scrollable, it is so possible to add scrollbars to
the Composite widgets by using the SWT.H SCROLL or SWT.V SCROLL style bit
constants. Furthermore, composite properties as the background colour can
be set except the text value.
The following code is an example that shows how to place a composite within
a Composite. The first Composite has a border and a coloured background,
so it is easily spotted on the screen. In order to use the setBackground()
method for any control, you need to import the Graphics library and create
a Color:
And this will produce the following result on the next page:
But first, note that if you do not give a border or a background to the com-
posite, you will not be able to distinguish it from the shell. The second com-
posite exists within the first. It has horizontal and vertical scrollbars, and a
list within the composite
Once the Table is created, it only has one column. And if you try to add any
items to the table, only the first field of the item will be displayed because
it is the wrong way to do it. In order to display all the fields you want, you
need to define TableColumns objects.
TableColumn
When you add TableColumns to your Table, you can use the following style
bit constants: SWT.LEFT, SWT.RIGHT and SWT.CENTER.
Do not forget to set the column width, and its name if you want to display
the headers with the setWidth() and setText() methods.
After you have created and added the columns to your table, you are now
ready to add the TableItems objects.
TableItem
When you add a TableItem to your Table, you can not use any style bit
constant (except SWT.NONE if you want):
To set the text of an item, you can use the setText() method that will cre-
ate a TableItem with fields in the order that you defined them. If you want
to define one field at a time in a special order, you can use the setText(int,
string) method which places the text into a specific field in the record.
And now that you have created TableColumns and TableItems, your table is
full.
Let us have a look at three simple examples of tables and see the differ-
ent styles that can be used.
• The first table – just below – has a border, fixed size columns, with
different horizontal alignments.
• The second table – just below – has a CheckBox column. We can set
the checked status of the item through the code. There are no grid
lines, but the header is visible. This example also sets the background
color of one of the table items.
• The last example – just below – uses the FULL SELECTION style, which
means that when you select a TableItem, the whole item is highlighted
instead of just the first field. The first column is resizable (this mean
you can make it larger or smaller). Note that each three columns has
a different horizontal alignment. This example also shows how you can
pre-select an item.
But although the Combo widget is a Composite, it does not make any sense
to add child elements to it if they are not of the type String. So, an element
to a Combo widget can be added by using the add(String element) method.
The following SWT style bit constants can be used: SWT.READ ONLY, SWT.SIMPLE
or SWT.DROP DOWN.
Furthermore, if you want to add Items to a Combo, you can use the
setItems() method which takes an Array of Strings as argument. And then
to select one of the list items, you must use the select() method which
takes an integer as argument – the index of the item you want to select.
In the following example three Combos will be created. The first is a drop-
down list whose location and size are set, the second a simple Combo whose
location and size are set at one time using the setBounds() method and the
third a Combo with no Items.
8.3.3 Tree
The Tree widgets are usually used to display informations (e.g. folders and
sub-folders for a file manager or classes and sub-classes for a class browser)
in a hierarchical format. And even if the Tree class is a Composite, you may
not add Composite classes to it except if it is of type TreeItem.
For a tree, the standard style bit constants are: SWT.MULTI to allow multiple
selections or SWT.SINGLE to allow the selection of only one item from the
Tree at a time and SWT.CHECK to add check boxes beside each item in the
tree. (As usual, you cannot specify SWT.SINGLE and SWT.MULTI at the same
time.)
The Tree we will create here with the following pieces of code allows multi-
ple selections, and has a border. As usual, the first parameter of the Tree
constructor is the Composite on which we want to place the tree, and the
second is the SWT style bit constants.
Once the Tree is created, we can now attach TreeItems to it. We will here
create the top-level TreeItem (i.e. the root). For this, the first parameter to
the constructor is the Tree that we want to attach the items to, the second
is the SWT style bit constant, and the (optional) last parameter is the index
at which to place the item in the tree. In the following code sample, you will
see how the first argument specifies that ”My Documents” will appear as the
middle element in the top-level of the tree, even it was added after the other
two items.
Then if you want to create children TreeItems out of these root-level nodes,
you can use a similar constructor, except that this time, instead of specifying
the Tree to attach them to, you will specify the TreeItem so that they will
appear under. In our code sample, both of these nodes will appear under the
”My Computer” TreeItem. As in the above case, we can use the optional last
parameter to specify the index at which the new element should be placed
in the sub-tree.
You can then continue the creating sub-trees process as many times as you
want only by creating more TreeItems out of other TreeItems. Here we extend
the Tree to a third level by creating a TreeItem ouut of the ”Local Disk”
TreeItem.
Note that we could also add a different image to each TreeItem by loading
the image and then using TreeItems setImage() method, as follows where
the image will appear to the left of the Item text.
The next step is to add a Listener to the tree. We will associate our Se-
lectionListener with the Tree as a whole, and so we will be allowed to use
the getSelection() method to return a list of the selected TreeItems. In
the example below, we are listening for changes in the selection(s), to get
an array of the TreeItems that are selected and print out the text from each
item. (For more informations on the SelectionListener, have a look to the
section 8.1.1)
And we can also listen for collapsing and expanding of the tree using a
TreeListener. We will print ”Tree collapsed” and ”Tree expanded” when the
corresponding event occurs as you can see in the following source code:
(Note that if you used a tree with the SWT.CHECK style bit constant, the
TreeItems getChecked() method could have been used to test whether a
particular Item in the tree had been checked.)
8.3.4 TabFolder
The TabFolder widget is usually used to select a page in a set of pages. Once
again, although it is a Composite you are not allowed to add Composite
widgets to it, except if it is of type TabItem. There are the two important
steps to create a TabItem:
1. if you want a Label on the tab, you need to use the setText() method
2. in order to populate the TabItem, you need to set the Control which it
contains, by using the setControl() method
In the following example, buttonComp is a Composite. Since you can only set
one Control into a TabItem, a Composite is usually desired. And then you
can add several Control widgets to the Composite that will appear on the
specified TabItem. In this code, you will see that Events for tab changing
are built into the TabItem and TabFolder controls.
As said, this example shows how to create a TabFolder with two TabItems
– one for buttons and one for labels. On the left, you see what it looks like
when the window initially appears, on the right, you see what the screen
looks like when you click on the ”Labels” tab.
8.3.5 CoolBar
The CoolBar widget provides an area in which you add items that would be
dynamically re-positionable. Obviously, you can add one or more ToolBar
widgets to a CoolBar. The CoolBar can contain one or more CoolItems.
And once again, although a CoolBar is a Composite widget, it is not allowed
to add other composite classes because the sub-elements of a CoolBar must
be of the type CoolItem. We can place whatever Controls we like on each
CoolItem. In the following example, we will create in a standard way a
bordered CoolBar and four CoolItems – one empty CoolItem, two CoolItems
containing Buttons and a final CoolItem containing a ToolBar – specifying
”bar” as the CoolBar to which they should be added.
When we use the pack() method on the Button, we set it to its correct
size. The Listener that we next add to the button will call bar.setLocked(boolean)
to lock (or unlock) the CoolBar each time it is clicked on. This means that
when you click on it at first, it locks and the Toolbar removes its ability to
click and drag the CoolItems around within the bar.
The next piece of code places a basic 2-button Toolbar on its own CoolItem.
Then, once we have created all the Controls we wanted, we can use:
the setControl() method to associate the Controls with the right Coo-
lItems, the setSize() method to set the initial size of each Control or the
setMinimumSize() method called on item3 to ensure that the CoolItem con-
taining the ToolBar does not shrink beneath the size we request – in this case
is the size of the ToolBar itself when the user rearranges the CoolBar.
In the end, we can use the setWrapIndices() method to wrap some Coo-
lItems onto the next row at a particular index and the setSize() is called
on Bar to specify its size on the Shell.
Here is what the Coolbar looks like initially (on the left) and after some
rearrangement, a locking of the CoolBar (on the right):
(Note that the most common use of CoolBars is to create dynamically re-
arrangeable Toolbars. For example, they are use in Eclipse. This is how
Eclipse and TeXnicCenter use them.)
But first, remark that the following style bit constants are available: SWT.PUSH,
SWT.CHECK to get a checkbox item, SWT.RADIO to get a radio button item,
SWT.SEPARATOR to provide an non-selectable dividing horizontal line between
other items and SWT.CASCADE.
Simple Menu
When you want to create the menu bar that spans the top of your Shell use
the following code which uses Menu and MenuItem widgets:
Then, let us add an MenuItem to this Menu bar. We will create a ”File”
MenuItem. (Note that if you launch your application now with only these
lines, you will see a Menu bar at the Shell top with only the ”File” option
displayed. But if you select one of the options, nothing will happen. So, ver-
ify that the style bit constant is SWT.CASCADE. Otherwise you will be unable
to attach a drop-down Menu to it.
We will now create a Menu to the File option and attach MenuItems to
it. (Note that the style constant for the menu must be DROP DOWN)
Finally, we can now add a MenuItem to our file Menu, and then associate an
action with it to create a basic selectable MenuItem on the ”File” Menu.
Repeating these steps with more Menus and MenuItems is all you need to
do to create a useful set of simple menus for your program.
And on the following page, you will see the resulting menu:
Advanced Menu
Let us now start the longer example with the same initial code as the
first example. The following code demonstrates how to use the SWT.CHECK,
SWT.SEPARATOR and SWT.RADIO options. It will create a separator and a
CheckBox-style MenuItem followed by radio-button styled MenuItem.
In the next few lines we add Listener s to the Check- and Radio- MenuItems,
which output their current values (true or false) to the console.
Let us now add a sub-menu that branches off of the file menu, which is
very similar to how we attached our ”File” Menu to the Menu bar. Then we
create a new MenuItem with the SWT.CASCADE style bit constant, and a new
Menu to attach to it. We then call setMenu() method on the MenuItem to
which we attach the new menu.
In the next few lines we add a MenuItem to our new sub-menu. This new
MenuItem that we have added will be called ”SubAction”.
Notice that in the setText() method call, there is an ampersand(&) before
the letter 0 S0 . This will create a mnemonic for the SubAction command, so
that when the submenu is displayed, if you press the S KEY it will select it
as if you had used the mouse. Then the call to setAccelerator() associates
the SubAction MenuItem with the key combination Control-S, so the user
can execute the SubAction command without bringing up the menu.
There exist several ways to add Listener s that we did not look at in our
simple example. One of these is the ability to add listeners to the Menus
(rather than to the MenuItems as we did before.) Let us add a MenuListener
to our sub-menu, which notifies us whenever it is shown or hidden.
The final listener type is the HelpListener. This mean that by pressing the
F1/HELP KEY, the HelpListener is activated.
You can see just below the result of the preceding codes. If you select
the ”Enable” SubAction option, you will enable SubAction and if you type
Ctrl+S, this will execute SubAction as well, but only if Enable SubAction is
checked. Note that all the listeners print messages to the console when they
are activated.
It exists other facilities available for Menus and MenuItems, but we have
attempted to cover the majority of the useful ones. Next we will look briefly
at a simple pop-up menu.
the Composite that has a pop-up menu associated is a kind of shortcut that
will make appear a floating menu beside your mouse allowing you to select
an option from a list like a regular menu. In the example of this section, a
Button will be created in a Composite on a Shell. Then two Pop-up Menus
will be created. The first will be associated with the Shell and the Composite
while the other with the Button.
So, we create a Menu, as we did in the section 8.4.1, except that its style
bit constant will be SWT.POP UP. We then add an MenuItem and attach a
Listener to capture its selection events.
Then we repeat the process, with the Menu associated with the Button.
Next we create the Composite and Button, and place them on the Shell.
Now if we run the code, and right-click on the Button, it will display one
menu, but if we right-click the Composite or Shell, we get another menu with
different options. In the following screen shots we can see the Pop-up menu
that is displayed when right-clicking on the Button (on the left) and outside
of it (on the right).
Layouts
All the component in the Composite are affected by the layout properties.
Some layouts support layout data objects to set different properties for each
Control within a Composite. These properties can be set by using a layout’s
87
member variables. If you are familiar with SWING, you would probably
search for methods to set and get these member variables. In SWT, it is
different: you read and write to those variables directly.
9.1 FillLayout
The FillLayout is the simplest (and set by default) Layout. If there is only
one component, the FillLayout makes it fills the whole available area of the
composite. If there are more than one components, it forces them all to get
the same size in a column (or a line, depending on the style bit constant of
the Layout). No options are available to control the spacing, the margins or
the wrapping.
The style bit constants for this layout are: SWT.HORIZONTAL (used by default)
or SWT.VERTICAL to position the controls either in a single row or a column.
You can set this in the constructor, or later as a field of the layout.
The FillLayout is usually used for ToolMenu bar, Group or Composite having
only one child. Besides that, it might be used to stack the check boxes or
radio buttons in a group.
The width and height of a Control within a Composite are determined by the
parent composite. Initially, the height of any control is equal to the highest,
and the width of a control is equal to the widest.
9.2 RowLayout
The RowLayout is very similar to FillLayout (seen in the chapter 9.1). It
positions the Control s in the same way as the FillLayout: in rows or columns.
You can use the following code to use a RowLayout in your application:
• if the number of widgets does not fit in a row, it wraps them (wrap
field set to true by default) as you can see it (from left to right)
• a RowData is provided
Note that you can also use the following RowLayout fields: pack to force all
the component of a Composite to have the same size and justify to spread
the widgets of a Composite across the available space.
9.3 GridLayout
The GridLayout is the most useful, flexible and powerful layout.It lays out
the widgets in grids and has a lot of configureable properties we will see
below. To set a different property for a specific cell, you need to create a
GridData object and set this as the control’s layout data object.
To use this layout in your application, you can use the following code sample:
9.4 FormLayout
The FormLayout is, as the GridLayout, a very flexible layout, but it works in
a completely different way. Indeed, in contrast to GridLayout, FormLayout is
independent from the complete layout. The position and size of the compo-
nents depend on one Control. The properties you can set are marginWidth
and marginHeight that allow to set the margin values. You can use the
following code to manage your application with a FormLayout:
You can see the result of the previous code on the following page (on the
right, when you try to increase the size of the window)
9.5 StackLayout
The StackLayout is quite different from the other layout managers. Only one
Control is displayed at a time instead of every Control s for the other layouts.
We usually use the StackLayout for the property pages, wizards,... Its most
usual properties are: marginHeight, marginWidth to set the margin values
and topControl to specify the Control that is displayed at the top of the
stack.
And here is the result: from the left to the right, we only clicked on the
”Show next group” button:
SWT editors
As you can see, during this tutorial, we decided to explain the SWT installa-
tion, philosophy and how to implement an application with this Java library
developed by IBM. But, as visual editor for Swing and AWT are available,
free SWT visual editors appeared at the end of the year 2004.
That is why we decided to make this appendix to give you some url ad-
dress where to find free- or shareware versions. Most of the freeware versions
are developed as Eclipse plug-ins because it is a library developed by IBM
and specially used by the Eclipse environment (developed by IBM, too). But
some other – shareware this time – can be used by other IDE as WebSphere.
• http://dev.eclipse.org/viewcvs/indextools.cgi/vep-home/WebContent/docs/
newAndNoteworthy/1.0.0-final/vep-news-final.html?rev=1.2 (freeware)
• http://www-106.ibm.com/developerworks/opensource/library/os-ecca/ (free-
ware)
• http://www.instantiations.com/swt-designer/home content.html (shareware)
101
Semester project, 2004 102 SWT Tutorial
Appendix B
103
Figure B.1: custom ZoomedScrolledCanvas code sample
• And finally, to setup the label, we need to give its layout data and some
text.
The next thing we must do is to draw the image onto the canvas. For this,
we will first set the size of the Canvas and of the ScrolledComposite and an
image that will appear in its full size. We then need to add a paint listener
to (re-)draw the image that will be scaled to the size of the Canvas. This is
really useful, because when we are zooming on the picture, we will only need
to change the size of the canvas and when this happens, a paint event will
be triggered and the image will be redrawn every time using the size of the
Canvas. Note that we also have a dispose listener to dispose of the image
when the Canvas is disposed.
Now that our appearance Control is set up, we will add a SelectionLis-
tener to the Scale to zoom in or out of the image depending on the changed
value on the Scale. In this Listener, we calculate a new size based on the
zoom factor and resize the canvas. (When the canvas is resized in the Selec-
tionListener, a PaintEvent will be generated by the PaintListener placed on
our Canvas, and so the image will be drawn at its new size.
And finally, to see the widget in action, we use it in exactly the same way
as we would use any widget.
When we move the zoom scale down, the image gets smaller:
When we move the zoom scale up, the image gets larger and we can scroll
through it:
111