Beruflich Dokumente
Kultur Dokumente
By Kalman Hazins
(kalman.hazins@jhuapl.edu)
Links
Tutorials:
http://www.cs.umanitoba.ca/~eclipse/
Additional tutorials:
http://www.developer.com/java/other/article.php/10936_3330861_1
Code examples:
http://www.java2s.com/ExampleCode/SWT-JFace-
Eclipse/CatalogSWT-JFace-Eclipse.htm
http://www.eclipse.org/swt/
Eclipse - SWT Gui builders:
Jigloo - http://www.cloudgarden.com/jigloo
Eclipse ve (visual editor)
SwtGuiBuilder (trial)
Additional free IDEs with builders– Jdeveloper, NetBeans mattise
Agenda
Creating widgets
SWT Layouts
Event Handling
Sample Application
History of Java GUI
AWT – Abstract Windowing Toolkit
First released in 1995 as part of JDK 1.0 by Sun
Heavyweight GUI components – a Java component creates a peer
component on the operating system and the peer draws itself.
Least Common Denominator problem – for simple GUI components
creating a peer works, what about the components that are only
available on some platforms and not others? If you want to write code
that’s truly portable – you have to use components that are available on
all platforms
The logic makes sense – but how do you develop a serious application
using just the basic components (available on all platforms)?
You don’t …
Enter Swing
History of Java GUI (Cont.)
Swing (JFC – Java Foundation Classes)
Released in 1998 as part of JDK 1.1
Lightweight GUI components – no need for operating system
“peer”-based drawing. Let’s draw the components ourselves.
Lightweight – there is no actual weight (operating system
component) behind the Java component.
Nice toolkit with enhanced Model-View-Controller architecture
and superior graphics 2D library.
Portable? You bet. Any problems? Now that you are not actually
using the operating system components – you are just mimicking
the behavior of the operating system. Hence, the look and feel
as well as the response speed are not the same.
Swing has gotten much better with release 1.4.2 and 1.5 of SDK
Still, very few commercial applications are written in Swing.
History of Java GUI (Cont.)
SWT (Standard Widget Toolkit)
GUI toolkit released in November 2001
Was initially designed to write the now extremely famous and
popular Eclipse IDE
“Best of both worlds” approach – use native functionality when
available, and Java implementation when unavailable
Takes on the appearance and behavior of the native platform
Because of its close bond with the operating system, SWT
needs to be ported separately for every platform
Currently, implementations of SWT are already available for all
major desktop operating systems and some handheld devices
The code YOU write will be portable for all the platforms that
have SWT implementations for them (unless you decide to do
some platform specific stuff like OLE on windows)
http://www.eclipse.org/swt/ - SWT home page
Installing SWT
To compile and run SWT applications you need
1. SWT jars (usually just swt.jar)
2. SWT native libraries
System.out.println(System.getProperty(“java.library.path”));
which will give you a list of the directories in your “library path”.
You can then copy the native library files from C:\SWT to one of
those directories.
-OR-
1. import org.eclipse.swt.widgets.*;
2. import org.eclipse.swt.widgets.Shell;
If you are a Swing guy, and the above 3 things greatly bother you – you
can write a simple SWTUtil class to help you deal with it …
Homegrown SWT Utility
SWTUtil.java
import org.eclipse.swt.widgets.*;
// This loop keeps the shell open constantly listening for events
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
SWT Utility in Action
“Simplest SWT program”
rewritten using SWTUtil class
import org.eclipse.swt.widgets.*;
SWTUtil.openShell(shell);
}
}
Widget creation explained
A widget in SWT is created by
1. Specifying parent
2. Specifying style
A parent is the container that the widget is created inside of (e.g.
Shell).
Style is any constant from the SWT class (SWT.PUSH,
SWT.BORDER, SWT.LEFT etc).
All styles applicable to the widget can be found in the Javadoc for
that widget (as well as its superclasses if any).
If more than one style is desired – separate them out with a “|”
bitwise operator (e.g. SWT.MULTI |
SWT.V_SCROLL|SWT.H_SCROLL| SWT.BORDER creates a multiline
textarea that has vertical and horizontal scrollbars and a border
around it). If no specific style is desired – use SWT.NONE. The style
you are requesting is only a hint, so if the underlying platform
doesn’t support it – you are out of luck.
Label
Unselectable, uneditable text
SWT.VERTICAL or SWT.HORIZONTAL can be used together with
SWT.SEPARATOR to create a label that is a horizontal/vertical separator
LabelWorld.java
1. import org.eclipse.swt.SWT;
2. import org.eclipse.swt.layout.GridLayout;
3. import org.eclipse.swt.widgets.*;
ButtonWorld.java
1. import org.eclipse.swt.SWT;
2. import org.eclipse.swt.layout.GridLayout;
3. import org.eclipse.swt.widgets.*;
TextWorld.java
1. import org.eclipse.swt.SWT;
2. import org.eclipse.swt.layout.GridLayout;
3. import org.eclipse.swt.widgets.*;
ListWorld.java
1. import org.eclipse.swt.SWT;
2. import org.eclipse.swt.layout.GridLayout;
3. import org.eclipse.swt.widgets.*;
10. String[] items = "One Two Three Four Five Six".split(" ");
11. List one = new List(shell, SWT.SINGLE | SWT.BORDER);
12. one.setItems(items);
13. one.select(2);
14. List two = new List(shell, SWT.MULTI | SWT.BORDER);
15. two.setItems(items);
16. two.setSelection(items);
17.
ComboWorld.java
1. import org.eclipse.swt.SWT;
2. import org.eclipse.swt.layout.GridLayout;
3. import org.eclipse.swt.widgets.*;
10. String[] items = "One Two Three Four Five Six".split(" ");
11. Combo one = new Combo(shell, SWT.DROP_DOWN);
12. one.setItems(items);
13. Combo two = new Combo(shell, SWT.DROP_DOWN | SWT.READ_ONLY);
14. two.setItems(items);
15. Combo three = new Combo(shell, SWT.SIMPLE);
16. three.setItems(items);
17.
GroupWorld.java
1. import org.eclipse.swt.SWT;
2. import org.eclipse.swt.layout.GridLayout;
3. import org.eclipse.swt.widgets.*;
BrowserWorld.java
1. import org.eclipse.swt.SWT;
2. import org.eclipse.swt.browser.Browser;
3. import org.eclipse.swt.layout.FillLayout;
4. import org.eclipse.swt.widgets.Shell;
FillLayoutExample.java
1. import org.eclipse.swt.SWT;
2. import org.eclipse.swt.layout.FillLayout;
3. import org.eclipse.swt.widgets.*;
RowLayoutExample.java
1. import org.eclipse.swt.SWT;
2. import org.eclipse.swt.layout.RowData;
3. import org.eclipse.swt.layout.RowLayout;
4. import org.eclipse.swt.widgets.*;
StackLayoutExample.java
1. import org.eclipse.swt.SWT;
2. import org.eclipse.swt.custom.StackLayout;
3. import org.eclipse.swt.events.*;
4. import org.eclipse.swt.widgets.*;
10. // Username
11. new Label(shell, SWT.RIGHT).setText("Username:");
12. Combo cmbUsername = new Combo(shell, SWT.DROP_DOWN);
13. cmbUsername.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
14. cmbUsername.setItems(new String[]{"Howard", "Admin", "Kalman"});
15. cmbUsername.setText("Admin");
16.
17. // Password
18. new Label(shell, SWT.RIGHT).setText("Password:");
19. new Text(shell, SWT.BORDER | SWT.PASSWORD).GridData(GridData.FILL_HORIZONTAL));
20.
27. shell.pack();
28. SWTUtil.openShell(shell);
29. }
30. }
FormLayout
12. // input
13. Label lblInput = new Label(shell, SWT.RIGHT);
14. lblInput.setText("Type in here:");
15. GridData data = new GridData(GridData.HORIZONTAL_ALIGN_END);
16. lblInput.setLayoutData(data);
17. Text input = new Text(shell, SWT.BORDER);
18. input.addVerifyListener(new VerifyListener() {
19. public void verifyText(VerifyEvent vEvent) {
20. vEvent.doit = false; // don't allow anything but numbers
21. if(!numbersOnly || vEvent.character == '\b') {
22. vEvent.doit = true;
23. }
24. else if(Character.isDigit(vEvent.character) && numbersOnly) {
25. vEvent.doit = true;
26. }
27. }
28. });
EventHandling.java
39. shell.pack();
40. SWTUtil.openShell(shell);
41. }
42. }
syncExec() / asyncExec()
You should only be updating user interfaces from the user interface thread.
For example, say you create a Label in your main thread. Then, you have a separate thread that
does some sort of a long computation. Then, you want to update your label with the result of the
second thread’s computation. You CANNOT just call label.setText(newValue) in your second
thread.
Instead, you have to call either syncExec(Runnable) or asyncExec(Runnable) methods on the
instance of Display
// Say you run a thread that calculates new time approximately every second
// and tries to update a label
new Thread(new Runnable() {
public void run() {
Display display = shell.getDisplay();
while(!shell.isDisposed()) {
try {
display.asyncExec(new Runnable() {
public void run() {
clock.setText((new Date()).toString());
}
});
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
Sample Application
Goal: Write a cute browser in SWT (under
300 lines) that handles most HTML
CuteBrowser.java uses SWTUtil.java
Run the application on Windows XP
computer that has java installed