SWT Programming with Eclipse
By Koray Guclu
"The best way to predict the future is to invent it."—Alan Kay
1. Why SWT?
SWT is a cross platform GUI developed by IBM. Why has IBM created another GUI? Why have not they used existing Java GUI frameworks? To answer those questions, we need to go back to the early days of Java.
Sun has created a cross platform GUI framework AWT (Abstract Windowing Toolkit). The AWT framework uses native widgets but it was suffering from a LCD problem. The LCD problem causes loss of major platform features. In other words, if platform A has widgets 1–40 and platform B has widgets 20–25, the cross-platform AWT framework only offers the intersection of these two sets.
To solve this problem, Sun has created a new framework that uses emulated widgets instead of native widgets. This approach solved the LCD problem and provided a rich set of widgets but it has created other problems. For instance, Swing applications no longer look like native applications. Although they're the latest improvements in the JVM, Swing applications suffer performance problems that do not exist in their native counterparts. Moreover, Swing applications consume too much memory, which is not suitable for small devices such as PDAs and Mobile Phones.
IBM has decided that neither of the approaches fulfill their requirements. Consequently, IBM has created a new GUI library, called SWT,which solves the problems seen with the AWT and the Swing frameworks. The SWT framework accesses native widgets through JNI. If a widget is not available on the host platform, SWT emulates the unavailable widget.
2. Building Blocks of an SWT Application
Display, Shell, and Widgets are basic building blocks of an SWT application. Displays are responsible from managing event loops and controlling communication between the UI thread and other threads. Shell is the window in an application managed by the OS window manager. Every SWT application requires at least one Display and one or more Shell instances.
Figure 1. An SWT application from different perspectives.
Figure 1 shows an SWT application from different perspectives. The first diagram is the simplified inheritance diagram of the UI objects. The second diagram is the containment structure of the UI objects. The third diagram is the created UI.
If an application uses multiple threads, each thread uses its own instance of a Display object. You can get the current active instance of a Display object by using the static Display.getCurent() method.
A Shell represents a window in a particular operating system. A shell can be maximized, normal, or minimized. There are two types of shells. The first one is the top-level shell that is created as a child, main window of the Display. The second one is a dialog shell that depends on the other shells.
The type of a Shell depends on style bits passed to the Shell's constructor. The default value of a Shell is DialogShell. That is to say, if nothing is given to the parameter, it is by default a DialogShell. If a Display object is given to the parameter, it is a top-level shell.
Some widget properties must be set at creation time. Those widget properties are called style bits. Style bits are defined as constants in SWT class, for example, Button button = new Button( shell, <stylebits></stylebits>). It is possible to use more then one style bit by using the OR operation |. For instance, to use a bordered push button, you need to use SWT.PUSH | SWT.BORDER as style bit parameters.
3. Environment Set-Up
Developing an SWT application is different from developing a Swing application. To begin with an SWT application development, you need add SWT libraries to your classpath and set necessary environment variables accordingly.
The first library that you need is the swt.jar file that is under the ECLIPSE_HOME\eclipse\plugins\org.eclipse.swt.win32_2.1.0\ws\win32 directory. Depending on the version of the Eclipse that you are using, you might need to use a different directory. The swt.jar file must be added to your classpath to make this go to Project->Properies->JavaBuildPath->Libraries->Add Variable -> Eclipse Home ->Extend and select the swt.jar library under the director abovey and then click on OK.
Afterwards, you will be able to compile an SWT application but, because of a runtime exception shown below, it won't be able to run because the swt.jar library uses native libraries. You need to set the java.library.path environment variable to use native libraries in Java.
Console output |
java.lang.UnsatisfiedLinkError: no swt-win32-2133 in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1403) at java.lang.Runtime.loadLibrary0(Runtime.java:788) at java.lang.System.loadLibrary(System.java:832) ... at org.eclipse.swt.widgets.Display.<init></init>(Display.java:287) at Main.main(Main.java:25) Exception in thread "main" |
To set the java.library.path variable, go to Run-> Run...-> Java Applicaton-> New ->Arguments -> VM Arguments. Thereafter, if neccesary, modify the path below and paste it to the VM Arguments field.
-Djava.library.path=c:\eclipse\plugins\org.eclipse.swt.win32_2.1.0\os\win32\x86
![]() | Loading native libraries |
If you need to load any native library that your application uses, you can use the Runtime.getPlatform.loadLibrary("libraryname") method. |
Finishing these steps will enable you to run an SWT application within your eclipse environment.
4. Your First SWT Application
Creating a typical SWT application requires the following steps:
- Create a Display
- Create one or more Shells
- Set a Layout manager of the Shell
- Create widgets inside the Shells
- Open the Shell window
- Write an event dispatching loop
- Dispose display
You can use the following code template to quickly run the code snippets in this article. You can copy and paste the code to the area, as shown in Source 1.
Source 1. SWT application template |
import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class SliderExample { public static void main(String args[]) { Display display = new Display(); Shell shell = new Shell(display); shell.setLayout( new RowLayout()); // ------------------------ // Your code comes to here. // ------------------------ shell.pack(); shell.open(); while( !shell.isDisposed()) { if(!display.readAndDispatch()) display.sleep(); } display.dispose(); } } |
This example displays an empty window. You can add your widgets to the template above. Every SWT application requires a Display and one or more
Shells. The Shell is a composite object; it can contain other composite objects. If the
layout of the shell is not set, added widgets to the Shell won't be visible. The Shell window must be
opened to be displayed.
The event handling loop reads and dispatches 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 of the
Display, when the Shell is discarded.
5. Running SWT Applications Outside of Eclipse
To run the application without using Eclipse, the swt.jar library must be in your classpath, and the java.library.path enviroment variable must be set properly. Depending on the host platform, the appropriate native library file must be available. For the Windows platform, you can do the following to make the native library configuration for your application:
- Put swt.dll in the same directory as the program.
- Put swt.dll in the JAVA_HOME\bin\ directory.
- Put swt.dll in the c:\windows\system32 directory.
javac classpath c:\swt\swt.jar HelloWorld.java
Java classpath c:\swt\swt.jar;. Djava.library.path=c:\swt HelloWorld
The java.library.path is the required environment variable for the JNI. If you don't set this environment, your DLL class is not accessible. In that case, the application cannot run properly and throws an exception.
![]() | SWT libraries |
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 under the http://www.eclipse.org/downloads directory. |
6. SWT Packages
The SWT consists of the following main packages. Definitions of the packages are taken from the Eclipse API documentation. You can find the API documentation on the Eclipse Web site.
org.eclipse.swt: contains classes that define constants and exceptions that are used by SWT classes. An SWT package 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 etc. constants.
org.eclipse.swt.widgets: Contains most core SWT widget components, including the support interface and classes.
org.eclipse.swt.events: Defines typed events, listeners and events, that SWT components use. This package contains three different groups of classes: Listener interfaces, Adapter classes, and Event class.
org.eclipse.swt.dnd: Contains classes for drag-and-drop support of the SWT widgets.
org.eclipse.swt.layout: Contains classes providing automated positioning and sizing of the SWT widgets.
org.eclipse.swt.print: Contains classes providing print support for the SWT widgets.
org.eclipse.swt.graphics: Package provides the classes which implement 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 displaying them and the public API for loading/saving them.
7. Dialogs
Dialog implementations are native. That is to say, dialogs, like widgets, are platform components. Dialogs in SWT are derived from the Dialog abstract class. A dialog is not a widget but it can contain widgets.
Figure 2. Dialog class hierharcy.
There are different types of dialogs available. Some dialogs can have specific properties. A a dialog can be used as shown in Source 2.
Source 2. MessageBox example |
MessageBox messageBox = new MessageBox(shell, SWT.OK|SWT.CANCEL); if (messageBox.open() == SWT.OK) { System.out.println("Ok is pressed."); } |
Each dialog's open() method returns different types. For instance, the MessageBox dialog returns int from the open() metod. Therefore, one must write different conditions to handle the return value for each dialog.
ColorDialog shows a color selection pallet. It returns an RGB object from return method.
DirectoryDialog enables you to select a directory. It returns A String from THE open() method. The returning value is the selected directory. It is also possible to set additional filters to filter the directories.
The Font dialog enables a user to select a font from all available fonts in the system. It returns a FontData object from the open() method.
FileDialog enables a user to select a file. Additionally, you can set an extension filter, path filter, and filename filters. This dialog has the styles shown in Table 1:
Table 1. SWT Dialog style bit constants | |
SWT.OPEN | Shows Open button in the dialog |
SWT.SAVE | Shows Save button in the dialog |
PrintDialog enables a user to select a printer before starting a print job. It returns a Printer Data object from the open() method.
The MessageBox dialog is used to give feedback to the user. You can combine different styles by the | operation as shown in Source 3.
Source 3. MessageBox example |
MessageBox messageBox = new MessageBox(shell, SWT.OK| SWT.CANCEL| SWT.ICON_WARNING); messageBox.setMessage("www.korayguclu.de"); messageBox.open(); |
The resulting message box of the above example is shown in Figure 3.
Figure 3. MessageBox dialog.
Available button constants are listed below. A combination of different buttons can be made by using the | operation. The SWT framework builds the dialog depending on the style bits. The button constants are: SWT.ABORT, SWT.OK, SWT.CANCEL, SWT.RETRY, SWT.IGNORE, SWT.YES, and SWT.NO.
Table 2 shows a list of available icons to be used by dialogs.
Table 2. SWT icon style bit constants | |
SWT.ICON_ERROR | ![]() |
SWT.ICON_INFORMATION | ![]() |
SWT.ICON_QUESTION | ![]() |
SWT.ICON_WARNING | ![]() |
SWT.ICON_WORKING | ![]() |
8. Widgets
The SWT GUI objects derived from Widget and Control classes. The Widget object is the base class and defines methods common to all GUI classes. The Control class is the base class of all the windowed GUI classes, which means that the components derived from Control require a window or dialog to be displayed.
Menu objects also require a window to be displayed, but this requirement is indirectly satisfied. A Menu object requires a Control object.
Figure 4. Widget class hierarchy.
Figure 4 shows the widget class hierarchy. The Widget, Item, ScrollBar, and Control classes are abstract classes.
8.1. Widget Events
Widget events are summarized in Table 3. For the sake of simplicity, the table contains only the event names. It is easy to figure out the name of an event class by using this <eventname></eventname>Event. Likewise, the name of the associated listener can be figured out by using <listener name=""></listener> Listener. Each event does not have a matching adaptor class. For that reason, events having adaptors are marked in bold. The name of an adaptor can be figured out by using <eventname></eventname>Adaptor.
Examples:
Event Name is a Control, event class is a ControlEvent, listener class is a ControlListener, adaptor class is a ControlAdaptor.
Table 3. SWT Events | ||
Event Name | Widgets | Generated When |
Arm | MenuItem | a menu item is highlighted |
Control | Control, TableColumn, Tracker | a control is resized or moved |
Dispose | Widget | a widget is disposed |
Focus | Control | a control gains or loses focus |
Help | Control, Menu, MenuItem | the user requests help (e.g. by pressing the F1 key) |
Key | Control | a key is pressed or released when the control has keyboard focus |
Menu | Menu | a menu is hidden or shown |
Modify | Combo, Text | a widget's text is modified |
Mouse | Control | the mouse is pressed, released, or double-clicked over the control |
MouseMove | Control | the mouse moves over the control |
MouseTrack | Control | the mouse enters, leaves, or hovers over the control |
Paint | Control | a control needs to be repainted |
Selection | Button, Combo, CoolItem, List, MenuItem, Sash, Scale, ScrollBar, Slider, StyledText, TabFolder, Table, TableColumn, TableTree, Text, ToolItem, Tree | an item is selected in the control |
Shell | Shell | the shell is minimized, maximized, activated, deactivated, or closed |
Traverse | Control | the control is traversed (tabbed) |
Tree | Tree, TableTree | a tree item is collapsed or expanded |
Verify | Text, StyledText | a widget's text is about to be modified |
8.2. Useful widgets
Figure 5. Control class hierarchy.
All Control classes can be bordered. You can add a border to a control class by using the SWT.BORDER constant.
![]() | SWT style constant |
It is required to specify a style constant (style bit). If you do not know which constant to use or if you do not want to specify it, you can use SWT.NULL. |
8.2.1. Buttons
A button can have different styles. The style of a button depends on its defined style bit. A list of buttons and their style constants is shown in Table 4.
Table 4. SWT Button style bit constants and examples | ||
Constants | Example | Description |
SWT.ARROW | ![]() | A button to show popup menus etc. Direction of the arrow is determined by the alignment constants. |
SWT.CHECK | ![]() | Check boxes can have images as well. |
SWT.PUSH | ![]() | A push button. |
SWT.RADIO | ![]() | Radio buttons can be used in a group. |
SWT.TOGGLE | ![]() | Like SWT.PUSH, but it remains pressed until a second click. |
8.2.2. Slider, Scale, and ProgressBar widgets
Scale represents a range of selectable continues values. The range can be specified by the setMinimum() and setMaximum() methods of the Scale class. You can get the selection value by using the getSelection() method. A scale can only have one selected value at a given time. That is to say, it is not possible to have multiple selections.
Figure 6. Slider and Scale widgets inside a Group.
Depending on the parameters passed to the constractor, it is possible to create different scale and slider widgets. The slider and scale constants are shown in Table 5.
Table 5. SWT slider & scale style bar constants | |
SWT.HORIZONTAL SWT.VERTICAL | Shows horizontal or vertical widget |
Optionally, you can use the SWT.BORDER constant to create a border around a scale widget. This constant has no effect on the slider widget.
Source 4. Slider widget example |
final Slider slider = new Slider(shell,SWT.VERTICAL); slider.setMinimum(0); slider.setMaximum(100); slider.setIncrement(5); slider.setPageIncrement(10); slider.setSelection(25); slider.addSelectionListener( new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { System.out.println("Selection:"+ slider.getSelection()); } } ); |
The ProgressBar widget is similar to the Slider and Scale widgets, but it is not selectable. It shows the progress of a task. You can use the SWT.SMOOTH and SWT.INTERMINATE constants with the ProgressBar widget.
8.2.3. Text widget
A Text widget can be used to show or to edit text. Alternatively, you can use a StyledText widget to display the text by using a different font and color. The StyledText widget allows you to set the foreground, background color, and font for a given range within a text block.
Figure 7. Text widget.
It is possible to create a Text widget with the constants shown in Table 6. A Text widget is a scrollable widget. Therefore, the SWT.H_SCROLL and SWT.V_SCROLL constants can be used to add scroll bars to a Text widget.
Table 6. SWT Text style bit constants | |
SWT.MULTI SWT.SINGLE | Shows a single line or multi line widget |
SWT.READ_ONLY | Creates a read-only widget |
SWT.WRAP | Wraps the text |
Source 5 is a simple Text widget usage example.
Source 5. Text widget example |
Text text = new Text(shell, SWT.MULTI|SWT.WRAP); |
8.2.4. List widget
A List widget can be used to display a list of selectable string values. In the case of a selection, the List object sends a notification event to its listeners. The type of a selection can be single or multiple selections. The type of the selection is determined by the SWT.SINGLE or SWT.MULTI constants. The List widget is a scrollable widget. Therefore, the SWT.H_SCROLL and SWT.V_SCROLL constants can be used to add scroll bars to a Text widget.
Figure 8. List widget.
The following code snippet shows a simple List widget example.
Source 6. List example |
final List list = new List(shell,SWT.MULTI); for (int i = 1; i < 11; i++) { list.add(i+".)www.korayguclu.de"); } list.addSelectionListener( new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { List list = (List) e.getSource(); String[] str = list.getSelection(); for (int i = 0; i < str.length; i++) { System.out.println("Selection: "+str[i]); } } } ); |
8.2.5. Sash widget
A Sash widget can be used to display composite widgets in resizable areas. The following figure shows a Sash widget example.
Figure 9. Sash widget.
A basic sash example can be seen below.
Source 7. Sash example |
Button button = new Button(shell,SWT.PUSH); Sash sash = new Sash(shell, SWT.VERTICAL); Button button1 = new Button(shell,SWT.PUSH); |
8.3. Composite Widgets
Composite widgets can contain other composite widgets. The Composite class is the parent class of the composite widgets.
Figure 10. Composite can contain other composite classes.
Composite classes can contain other composite classes. This containment is built up by using the constructor of a composite widget class. In contrast to Swing, there is no add() method; instead, you must use constructors to build up a containment structure.
As can be seen from Figure 10, the Shell class is also a composite class. That is to say, the Shell object can contain other composite classes.
Composite widgets are Scrollable, which means that it is possible to add scrolls to the composite widgets by using the SWT.H_SCROLL and SWT.V_SCROLL constants.
8.3.1. Table widget
A Table widget can display a set of String items or Images. In contrast to other composite widgets, it is not possible to add composite controls to the table widget. A sub component of a table widget must be of the TableItem type.
Figure 11. Table widget.
The constants in Table 7 can be used with the table widget.
Table 7. SWT Table style bit constants | |
SWT.MULTI SWT.SINGLE | Enables a single or multi selection |
SWT.FULL_SELECTION | Enables full row selection |
SWT.CHECK | Displays a check box at the beginning of each row |
The code snippet in Source 8 shows a table widget usage containing two columns.
Source 8. Table widget example |
final Table table = new Table(shell,SWT.SINGLE); TableColumn col1 = new TableColumn(table,SWT.LEFT); col1.setText("Coloumn 1"); col1.setWidth(80); TableColumn col2 = new TableColumn(table,SWT.LEFT); col2.setText("Coloumn 2"); col2.setWidth(80); TableItem item1 = new TableItem(table,0); item1.setText(new String[]{"a","b"}); TableItem item2 = new TableItem(table,0); item2.setText(new String[]{"a","b"}); table.setHeaderVisible(true); table.setLinesVisible(true); |
8.3.2. Combo widget
A Combo widget allows users to select a value from a list of values or optionally enter a new value. The combo widget is similar to the List widget, but it uses a limited space.
Although the combo widget is a composite, it does not make sense to add child elements to it. Its elements must be of the String type. An element to a combo widget can be added by using the add(String element) method defined in the combo class.
Figure 12. Combo boxes in different styles.
The following SWT constants can be used with the Combo widget.
Table 8. SWT Combo style bit constants | |
SWT.DROP_DOWN | Drop-down combo box |
SWT.READ_ONLY | Read-only combo box |
SWT.SIMPLE | Simple combo box (not drop-down combo box). See Figure 11. |
The following example shows a Combo widget's usage.
Source 9. Combo example |
final Combo combo = new Combo(shell,SWT.DROP_DOWN); for (int i = 1; i < 11; i++) { combo.add(i+".) element "); } combo.setText("Text"); combo.addSelectionListener( new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { System.out.println("Selection:"+ combo.getText()); } } ); |
8.3.3. Tree widget
A Tree widget represents a selectable hierarchy of items in a tree. Altough the Three class is a composite, it is not allowed to add composite classes to the Three class. Sub items of a Tree class must be of the ThreeItem type.
Figure 13. Tree widgets in different styles.
The following table shows a list of Tree widget constants.
Table 9. SWT Combo style bit constants | |
SWT.SINGLE SWT.MULTI | Allows single or multiple selections |
SWT.CHECK | shows a check box at the begining of each node |
A simple Tree widget example is shown below.
Source 10. Tree example |
final Tree tree = new Tree(shell,SWT.SINGLE); for (int i = 1; i < 11; i++) { final TreeItem item1 = new TreeItem(tree,SWT.NULL); item1.setText("node "+i); for (int j = 1; j < 6; j++) { final TreeItem item11 = new TreeItem(item1,SWT.NULL); item11.setText("node "+i+"."+j); } } tree.addSelectionListener( new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { System.out.println("Selection:"+ tree.getSelection()[0]); } } ); |
8.3.4. TabFolder
The TabFolder widget allows users to select a page from a set of pages. Although it is a composite, it is not allowed to add composite widgets. A widget that is to be added to a TabFolder must of the TabItem type. The content of a tab can be set by using the TabItem's setControl(Control control) method.
Figure 14. TabFolder widget
A simple TabFolder example is shown below.
Source 11. TabFolder example |
final TabFolder tabFolder = new TabFolder( shell, SWT.BORDER); for (int i=1; i<5; i++) { // create a TabItem TabItem item = new TabItem( tabFolder, SWT.NULL); item.setText( "TabItem " + i); // create a control Label label = new Label( tabFolder, SWT.BORDER); label.setText( "Page " + i); // add a control to the TabItem item.setControl( label ); } |
8.3.5. CoolBar widget
The CoolBar widget provides an area in which you add items on a dynamically positionable space.You can add one or more ToolBar widgets to a CoolBar. A CoolBar can contain one or more CoolItems. Although CoolBar is a composite widget, it is not allowed to add other composite classes. Sub elements of a CoolBar must be of the CoolItem type.
Figure 15. Coolbar widget
The following example shows a CoolBar widget's usage.
Source 12. CoolBar example |
CoolBar coolBar = new CoolBar(shell, SWT.BORDER); coolBar.setLayoutData( new FillLayout()); // create a tool bar which it // the control of the coolItem for (int k = 1; k <3; k++) { ToolBar toolBar = new ToolBar(coolBar, SWT.FLAT); for (int i = 1; i < 5; i++) { ToolItem item = new ToolItem(toolBar, SWT.NULL); item.setText("B"+k+"."+i); } // Add a coolItem to a coolBar CoolItem coolItem = new CoolItem(coolBar, SWT.NULL); // set the control of the coolItem coolItem.setControl(toolBar); // You have to specify the size Point size = toolBar.computeSize( SWT.DEFAULT, SWT.DEFAULT); Point coolSize = coolItem.computeSize (size.x, size.y); coolItem.setSize(coolSize); } |
8.4. A summary of controls having items
Some controls accept sub components as items. For example, a Composite component accepts composite components. Some components need only items. Such components are listed in Table 10.
Table 10. Components having items | ||
Widget | Item | Description |
CoolBar | CoolItem | Items are selectable, dynamically positionable areas of a CoolBar |
Menu | MenuItem | Items are selections under a menu |
TabFolder | TabItem | Items are Tabs in a TabFolder |
Table | TableItem TableColumn | Items are Rows in a table |
ToolBar | ToolItem | Items are Buttons on the tool bar |
Tree | TreeItem | Items are nodes in a tree |
Conclusion
SWT is the core of the Eclipse user interface. The Eclipse platform is based on the SWT library. To extend your SWT knowledge, you can download SWT examples from the SWT Web site.