Installing Eclipse. by Christopher Batty and David Scuse. Department of Computer Science, University of Manitoba, Winnipeg, Manitoba, Canada

Size: px
Start display at page:

Download "Installing Eclipse. by Christopher Batty and David Scuse. Department of Computer Science, University of Manitoba, Winnipeg, Manitoba, Canada"

Transcription

1 Installing Eclipse 1, 2 by Christopher Batty and David Scuse, University of Manitoba, Winnipeg, Manitoba, Canada Last revised: October 22, 2003 Overview: In this collection of documents, we describe how to develop Java applications that use the SWT (Standard Widget Toolkit) instead of using Java s Swing or AWT widgets. SWT applications are developed using the Eclipse workbench. By the end of this document, you will be able to create a stand-alone Java application (jar file) that uses the SWT and runs on either Windows or Linux. In this document, we describe the installation of Eclipse on Windows and Linux platforms and the creation of a simple Java program that uses the SWT. We have attempted to note common problems that affect the install and provide solutions to these problems. We used Windows XP Professional with the Java JRE and Eclipse 2.1 as the primary platform for illustrating the use of Eclipse, but issues specific to Linux (both GTK and Motif) are also described at the end of this document. Setting up Eclipse To begin, download the Latest Release version of Eclipse from the downloads page of the Eclipse website located at (If you would like to try using the most recent stable version of Eclipse containing the latest new features, you can install the 1 This work was funded by an IBM Eclipse Innovation Grant. 2 Christopher Batty and David Scuse Installing Eclipse University of Manitoba Tutorial 1 Page 1

2 Current Stable Build.) Ensure that you select the correct version for your particular setup. The download file should have a name similar to eclipse-sdk-2.1-win32.zip or eclipse-sdk-2.1-linux-motif.zip depending on the operating system and windowing system you use. For each release of Eclipse, a page identifies the downloads that are available. Note that the source code for the release is available at the end of the list. The link to the Supported Versions page provides more information on the specific requirements necessary for Eclipse. The download file is in.zip format and can be expanded with any standard decompression software. Expand it into the folder where you would like Eclipse to run from, (e.g. C:\Program Files\eclipse ). Note: There is no formal installation Installing Eclipse University of Manitoba Tutorial 1 Page 2

3 executable to run. To remove Eclipse you simply delete the Eclipse folder, because Eclipse does not alter the system registry. Eclipse requires that a Java Runtime Environment (JRE) be installed on your system. The minimum version is identified on the Supported Versions page. (A JDK comes with a JRE, so if you can write and run Java programs, you already have a suitable JRE.) Entering the command java version at the command prompt displays the version of the JRE. You can download and install Sun s Java 2 Standard Edition SDK for your particular operating system, available from Sun s website at Once you have a Java runtime environment installed, you can simply run the Eclipse executable located in the install directory. (If you do not have a Java runtime, Eclipse will display an error message and refuse to run.) When Eclipse is run for the first time, the following screen is displayed for a short period of time. Then, after the Eclipse splash screen (shown on page 1) is displayed, the Eclipse workbench screen is displayed. Installing Eclipse University of Manitoba Tutorial 1 Page 3

4 The Navigator, Outline, and Tasks areas of the screen are known as views, while the area labeled Welcome is called an editor. In general, views provide information and allow you to navigate and modify properties of files, classes, packages, etc. Editors are designed to allow you to edit the contents of various types of files. For example, you will write your Java code in a Java editor window. The combination of views and editors displayed on screen at a given time is called a perspective. The current perspective is called the Resource Perspective and is used to display and edit resources. The currently open perspectives are shown in the toolbar down the left side of the screen. Other perspectives that will be useful later include the Java Perspective for editing java files, and the Debug Perspective, for performing debugging tasks. Creating a Project To begin developing a Java program using Eclipse, you must first create a new project. From the File menu, select New -> Project. A New Project Wizard is displayed. On the first page, select Java in the tree list on the left, and choose Java Project from the choices on the right. Then select the Next button. Installing Eclipse University of Manitoba Tutorial 1 Page 4

5 In the Project name field, enter a name for your new project. If you enter invalid characters, an error message is displayed at the top area of the screen. All Eclipse Wizards display errors in this manner. You may choose to store your project in the default folder location which will be under <eclipse-installdirectory>\workspace\<project name> as in the following figure. Alternatively, you can uncheck the Use default checkbox, and specify another location for your project. When you have filled in these fields, hit the Next button. Installing Eclipse University of Manitoba Tutorial 1 Page 5

6 The next page of the wizard allows you to modify various properties of the project. For the time being, the only tab we will worry about is the Source tab. This determines how the various files will be stored within your project folder. The Projects, Libraries and Order and Export tabs deal with how Java locates and uses other projects and libraries that may be required for the project you are creating. For example, if we make use of the SWT user interface library, we must specify this under the Libraries tab (configuring SWT will be covered later in this document). These settings can all be modified later from the project s Properties dialog. The Eclipse source files are normally stored in their own directory in the project directory. Click the Add Folder button to create a separate source folder. Installing Eclipse University of Manitoba Tutorial 1 Page 6

7 Enter the name of the folder in which to store the.java files. A standard choice for this is usually src. The source folder is now displayed in the project hierarchy. Eclipse will then ask if you would like to update the output folder to <project name>/bin. This is where your output (usually *.class) files will be placed upon compilation. Choose Yes. Installing Eclipse University of Manitoba Tutorial 1 Page 7

8 The screen should now look like the following. To finish creating the project, you may now hit Finish. Eclipse now asks if you want to switch to the Java Perspective in the workbench. Creating a Java program When you finish creating the new Java project, the screen should look like the following. Installing Eclipse University of Manitoba Tutorial 1 Page 8

9 There are several things to note about this. The view on the left of the screen is now the Package Explorer, and the Outline view is on the right rather than the left. The reason for this is that we are now looking at a different perspective. Recall that a perspective is a combination of view and editor windows displayed on the screen. The currently displayed perspective is the Java Perspective, usually used for editing java files. The perspective seen earlier was the Resource Perspective. Notice also that a new button has been added to the tool bar down the left side of the screen. This button, which has a few shapes and a J on it, represents the Java Perspective. To switch between perspectives, simply click the button for the perspective you d like to see. More important than the change in perspective is the fact that our new project is now listed in the Package Explorer view on the left. We will use this view to navigate the packages, source files and libraries that comprise our project. If we click the + sign on the tree beside the project name, and expand it we should see two subfolders displayed. The first is labeled src. This is the folder in which our source java files will be placed. The second may be labeled differently, depending on the JRE that is installed. In the example to the left, the full path is: JRE_LIB C:\Program Files\Java\j2re1.4.1_03\lib\rt.jar This is the location of the JAR (Java archive) file that contains Sun s Java Libraries on this machine. If you expand it further, you can browse the packages and classes of the libraries. We can essentially ignore this library for now. The next thing we do is create a new class for our first program. Select the src folder in the Package Explorer. From the File menu, choose New -> Class. Alternatively, the button on the toolbar that looks like will also run the New Java Class wizard. (Note that you must be in the Java Perspective for this portion of the toolbar to be displayed.) Many other useful functions have buttons on the toolbar as well. For example, pressing is a quick way to run the New Java Project wizard. Installing Eclipse University of Manitoba Tutorial 1 Page 9

10 When the New Java Class wizard runs you should see the following screen: Enter the name of your class in the Name field. The Source Folder should be <project name>/src already, so leave it as is. (If the correct folder was not selected when you ran the Wizard, it may be incorrect and if so you should change it to reflect the correct location for your source files.) In the Package field, if you wish to put the new class in a particular package, you can browse for the package to use, or specify its name. If the package you specify doesn t Installing Eclipse University of Manitoba Tutorial 1 Page 10

11 exist, a new package by that name will be created. For our purposes we can simply use the default package, leaving the field blank. The Enclosing type field is only used if you are creating an inner class, which we are not. Using this wizard we can also select access specifiers and identify superclasses or interfaces we wish to extend or implement. Use the default settings. One feature of the wizard that can be useful is the auto-generation of method stubs (empty methods with the correct names, parameters and return values). If we were implementing or extending an interface or class, stubbing the inherited classes would be very helpful, since we would not have to continually refer back to the superclass to determine the method signatures. For now, check only public static void main (String[] args) which will stub the main method for us. If there were any errors in how you have set up your class, a descriptive error message will be displayed at the top of the page. Hit Finish to generate the new class. The screen should now look like this: You can see that in the central (editor) window, there is a new tab, with the title HelloWorld.java corresponding to the name of the class specified in the wizard. To switch between open files/documents, simply click the various tabs. To close one of the Installing Eclipse University of Manitoba Tutorial 1 Page 11

12 files, click the tab so that the file is selected, and hit the X button on the tab. To re-open a closed file, you can double-click on its name in the Package Explorer or Navigator views. Notice that in the Outline view, an outline of the currently selected class is displayed. It will show all fields and methods of the class. Double-clicking on a method/field will jump to its definition in the source code. The buttons at the top of the view allow you to set options such as displaying only public members, sorting the names alphabetically, or hiding fields. Edit the main() function of the HelloWorld class to contain the following line: System.out.println( Hello, World! ); We will use this simple program to verify that we can successfully run a basic Java program using the Eclipse environment. From the File menu, choose Save to save the file. When you save the file, Eclipse automatically compiles it, and updates the.class files. Note that if you do forget to save a file before running a program, Eclipse will prompt you to ensure that you have saved all the necessary files. The dialog for that looks like the following: Installing Eclipse University of Manitoba Tutorial 1 Page 12

13 Check the boxes for each file/resource you wish to save before running the program. Again, compilation will be performed, so the latest changes will be reflected in the.class files for the program. (For small projects, this automatic compilation is generally quite useful, but it can become a nuisance for very large projects, so there is a preference available to turn it off under Window->Preferences. Choose the Workbench in the tree on the left and uncheck Perform build automatically on resource modification. Ctrl+B or Projects->Rebuild All can be used to rebuild the project when necessary.) Running a Java program From the Run menu, select the Run option. You will see the following screen: Installing Eclipse University of Manitoba Tutorial 1 Page 13

14 This screen allows you to set up Launch Configurations. The general idea is to set up all the parameters and options for a particular run of your program. If there are different set-ups that you use repeatedly, such as running with different command-line parameters or different java libraries or runtimes, you can create a launch configuration for each set-up. This way, you can select the correct launch configuration, and the program will run with the correct parameters, rather than having to modify the parameters each time you run the program. Select the Java Application option as above and hit the New button. A new Launch Configuration for a Java Application will be created and displayed (both on the right and in the tree-view on the left). For those who are interested in the other options: - JUnit is a popular testing framework that is used to create automated tests for your Java classes. See for more information. - Run-time Workbench is used by developers who are creating plug-ins for Eclipse. It runs a new instance of the Eclipse Work-bench for testing the new plug-in. Assuming that the correct class was selected in the Package Explorer, most of the settings should be filled in automatically, as seen below. If the class or project names are incorrect, you can hit Search or Browse, respectively, to choose the correct name(s) from a list. By default, the name of the launch configuration be the currently active class. Installing Eclipse University of Manitoba Tutorial 1 Page 14

15 The Arguments tab allows you to specify command-line arguments to either the Java virtual machine (that your program runs on) or to your program. The JRE tab allows you to change which Java Runtime Environment you are using to run the program. The Classpath tab is for setting the paths on your system where the program will look for class files to run the program. The Source tab tells the system where to look for program source files, and finally the Common tab sets various options dealing with shared (versus local) launch configurations. The defaults for these other tabs will work fine for now. To continue, hit Run. The screen should look as follows after running the program. The console output is displayed in a new Console view at the bottom of the screen. Note that the name of JRE used to run the application is displayed at the top of the console window. Once a Launch Configuration has been defined, it is not necessary to go through the Run command each time that an application is run. Instead, click the run icon to run the current launch configuration (or use Ctrl-F11). If multiple launch configurations have been defined, clicking the down arrow beside the run icon displays a list of launch configurations that can be selected. Installing Eclipse University of Manitoba Tutorial 1 Page 15

16 Configuring Eclipse to use the SWT libraries In the previous section, we configured the Eclipse workbench to run a simple Java program. In fact, any Java program that uses only Sun s Java run-time libraries (including Swing and the AWT) can be run with this configuration. However, we are interested in using the Eclipse SWT (Standard Widget Toolkit) instead of Java s Swing and AWT GUI widgets. In this section, we describe how to set up Eclipse to use the SWT user interface libraries and to verify that the configuration works correctly. To begin, create a new class called SWTHello in the existing HelloWorld Project. Replace the auto-generated code with the following: import org.eclipse.swt.widgets.*; import org.eclipse.swt.*; public class SWTHello { public static void main(string[] args) { Display display = new Display(); Shell shell = new Shell(display); Label label = new Label(shell, SWT.NONE); label.settext("hello, World!"); shell.pack(); label.pack(); shell.open(); while(!shell.isdisposed()) if(!display.readanddispatch()) display.sleep(); display.dispose(); label.dispose(); Use the File menu (or Ctrl-S) to save the file. This should cause numerous errors to be displayed. Notice that the errors are displayed in several locations, typically using small red circles containing white X s. 1. The Package Explorer identifies each branch of the project tree leading to an offending class file(s). 2. The Outline view shows the methods in which the errors occur. 3. The central Java editor window signifies errors by squiggly red underlines, similar to the mechanism used in Microsoft Word to identify spelling errors. 4. Lastly, the Task view at the bottom of the screen now includes a list of tasks that are the errors returned by the Java compiler. Double-clicking the error message will move your cursor to the location of the related error in the editor window. You may also find the Task view useful for organizing your work. To add a new Task to the list, right-click in the list (or use the button on the right side Task view title bar). Installing Eclipse University of Manitoba Tutorial 1 Page 16

17 The source of these errors is that we have not included the SWT libraries in the project, so the compiler is unsuccessfully searching for the SWT packages and classes that the program requires. To resolve this, we must supply the program with the locations of both the Java classes for the SWT libraries and the native (OS-dependent) code that the SWT classes use at run-time. The classes are in swt.jar and the run-time routines are in the SWT DLL file. (The name of this DLL depends on the platform and current SWT version. In our configuration it is swt-win dll.) To indicate where to find swt.jar, first right-click on the project name in the Package Explorer, and choose Properties. This will bring up a Properties dialog containing many of the same settings that were available when creating the Project. Installing Eclipse University of Manitoba Tutorial 1 Page 17

18 In the tree-view choose Java Build Path. Then select the Libraries tab on the right side of the screen. Currently the only library listed is Sun s Java Runtime libraries necessary for any java program to execute. We now add swt.jar to this list. Select the Add External JARs button on the right side of the screen. This will bring up a standard file selection dialog, and you must now find swt.jar. Its location is dependent on your platform. The SWT FAQ (available from the Eclipse website) gives the following list of locations for various platforms: win32: INSTALLDIR\eclipse\plugins\org.eclipse.swt.win32_2.1.0\ws\win32\ gtk: INSTALLDIR/eclipse/plugins/org.eclipse.swt.gtk_2.1.0/ws/gtk/ motif: INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_2.1.0/ws/motif/ photon: INSTALLDIR/eclipse/plugins/org.eclipse.swt.photon_2.1.0/ws/photon/ macosx: INSTALLDIR/eclipse/plugins/org.eclipse.swt.carbon_2.1.0/ws/carbon/ Once you have found and selected swt.jar, select Open. The swt.jar file should now be displayed in the list of libraries. When you hit OK and close the Properties dialog, the errors displayed earlier should be eliminated. Installing Eclipse University of Manitoba Tutorial 1 Page 18

19 Click OK to close the window. However, we are still not done. If you try running the program at this point, you will get an error similar to: java.lang.unsatisfiedlinkerror: no swt-win in java.library.path. The SWT run-time DLL that swt.jar requires is not available to the program. There are several ways of resolving this problem (described in the SWT FAQ also). 1. The first approach is to specify the location of the DLL as an argument to the Java virtual machine when you run the program. This is done by editing the launch configuration for your program. From the Run menu, choose Run, and select the specific launch configuration for your program in the tree-view on the left. Choose the Arguments tab on the right side of the screen. This allows you to set arguments to your program (if it takes input from the command-line) and to set arguments to the virtual machine that affect how it runs. In the text area labeled VM arguments enter the following line: Installing Eclipse University of Manitoba Tutorial 1 Page 19

20 -Djava.library.path=<folder containing the SWT DLL> As with swt.jar, the location of the DLL is platform dependent. Windows: INSTALLDIR\eclipse\plugins\org.eclipse.swt.win32_2.1.0\os\win32\x86 Linux GTK: INSTALLDIR/eclipse/plugins/org.eclipse.swt.gtk_2.1.0/os/linux/x86 Linux Motif: INSTALLDIR/eclipse/plugins/org.eclipse.swt.motif_2.1.0/os/linux/x86 Note that if the path name contains spaces you must surround it with double-quotes, or you will get an error when launching the program. 2. The -D VM argument sets a system property, and in this case the property is the path where Java looks for libraries. A potential problem with the previous method is that you must remember to set this VM option every time you create a new launch configuration, which can be a nuisance. An alternative is to add the location of the DLL to the environment variable that Java uses for its library path. For Linux/UNIX modify LD_LIBRARY_PATH (as is described in more detail later in this document). For Windows, the PATH variable can be modified. On Win9X you can modify the PATH variable in the autoexec.bat file, and on NT/2K/XP it can Installing Eclipse University of Manitoba Tutorial 1 Page 20

21 be modified through My Computer -> Properties -> Advanced -> Environment Variables. 3. A third option is to determine a location that is already specified by java.library.path, and copy the SWT DLL to that folder. A recommended standard choice (for Windows) is your Windows\System32 folder, but note that any location specified in the path environment variable discussed above will work. The disadvantage of this method is that if you upgrade Eclipse and get a different version of SWT, you must remember to copy the new SWT DLL to this location again. 4. The final option is to just copy the DLL into the (root of the) project folder. This has the drawback that you must do it for each project that uses SWT, and if you upgrade to a newer Eclipse/SWT version, you have to copy the file again. Once you have selected and performed one of these options, the native code that enables the SWT to work will be available to the program, and it should run correctly. You should see a Shell (window), containing the text Hello, World! as shown below. Congratulations, you ve just run your first SWT application! Installing Eclipse University of Manitoba Tutorial 1 Page 21

22 Creating a JAR for a stand-alone SWT application Using the sample SWT application, we will now create an executable JAR file that can run from the command-line, outside of the Eclipse workbench. Right-click on the project name in the Package Explorer and choose the Export option. In the Export wizard page that appears, choose JAR file from the list, and click Next. In the JAR Export screen that follows, use the tree-view at the top of the page to verify that the correct project and files are selected to be exported. Usually the defaults are correct. Check the Export generated class files and resources box, and if you wish to include the source in the JAR file, also check Export java source files and resources. In the JAR file: text box, either type a location and name for the JAR file you would like to produce, or use the Browse button to select one using a file dialog. You can specify whether to compress the files and whether to automatically over-write files using the check boxes at the bottom. Installing Eclipse University of Manitoba Tutorial 1 Page 22

23 When you have completed this page, choose Next. (Not Finish!) On the page shown above, the default options will be fine, with the exception that you should check Save the description of the JAR in the workspace. This way if you later make changes and wish to export the JAR again, you do not need to go through the entire Export Wizard a second time. Hit the Browse button to choose a location and filename. Select the name of the project for which you are creating a JAR file and then enter a filename for the jar description file that will be created. (The suffix.jardesc will be appended to the name, unless you specify it yourself.) Installing Eclipse University of Manitoba Tutorial 1 Page 23

24 The result should look like this. Choose Next The final page of the JAR export Wizard allows you to set some of the available manifest options. The manifest is a text file that is included in the JAR file, and which provides information about the JAR file. For example, it can specify which is the Main class, what libraries the JAR depends on, whether the JAR is sealed, and much more. (Many of these options are not available from the Wizard.) Select the Generate the manifest file radio button if it isn t already selected. Check both Save the manifest in the workspace and Reuse and save the manifest in the workspace. These options together will allow you to make changes to the manifest, and have them reflected in the JAR file next time you generate it (using the JAR description file we asked to be generated on the previous page). This will be useful in identifying the SWT libraries as necessary for running your JAR file. Just as you did for specifying the jar description file, use the Browse button to select the project and enter a name for the manifest file. In the example below, the manifest name is HelloManifest. The Sun s java developer website explains package sealing as follows: A package within a JAR file can be optionally sealed, which means that all classes defined in that package must be archived in the same JAR file. You might want to seal a package, for example, to ensure version consistency among the classes in your software or as a security measure. The options in the middle of the page allow you to seal some or all of the packages in your JAR file. Lastly, the Main class: field specifies which class file contains the main method that will run your JAR file. Use the Browse button to choose the main class from a list of available classes that have main() methods. Installing Eclipse University of Manitoba Tutorial 1 Page 24

25 If you have done all this, choose Finish to generate the JAR file (as well as the manifest and jar description files.) Both the JAR description file and manifest files should now be displayed in the Package Explorer view. The exported JAR file should be found in the target location you specified in the wizard. However, since the application also requires the SWT libraries to run, we must again take some additional steps to allow the new JAR file to use them. First, we must make the JRE aware of swt.jar. There are essentially two ways to do this. The first is to add swt.jar to your JRE\lib\ext folder. This folder is used for extensions/libraries for java, so the system knows where to look for them. These libraries will then be available at runtime for all your java programs. If you use this technique, ensure that you find the correct library: the JRE is typically installed in the Program Files folder. There may be another JRE folder inside the Java SDK (if it is installed) but this is not the correct location. Installing Eclipse University of Manitoba Tutorial 1 Page 25

26 The second method is slightly more complex, but may be useful if you are distributing the program and cannot necessarily modify a user s JRE installation. First, copy swt.jar to the same folder that contains the JAR file you just created. The manifest file must be modified to specify the fact that the JAR has a dependency on swt.jar, and cannot run without it. We do this by adding a line to the manifest file. (You can open it in Eclipse by double-clicking its name in the Package Explorer just like a java file.) The line to add is: Class-Path: swt.jar This will allow the new JAR file to use the classes in swt.jar. Now, right-click on the JAR description file in the Package Explorer and choose Create JAR. If the JAR already exists (and it should if you ve followed the steps above), it will prompt you to ensure that you want to overwrite the file. Choose Yes. When the jar file is distributed, the swt.jar file must be distributed with the jar and must be located in the same directory as the jar file. Now, we need to make the SWT DLL available at run-time. Depending on the method you used to provide Eclipse with the location of the SWT DLL, you will need to perform similar steps now when running from the command-line. Option 1) If you used the Djava.library.path option, this option can also be specified when running the JAR from the command-line. java Djava.library.path= C:\eclipse\plugins\org.eclipse.swt.win32_2.1.0\os\win32\x86 jar HelloJAR.jar Options 2 or 3) If you added it to the PATH, then you are already done. The DLL is available everywhere. Option 4) If you copied the DLL to the project folder, you must now copy the DLL to the same folder as your new JAR file. You should now be able to execute the program from the command-line. Navigate to the correct folder, and typing the following command: java jar HelloJAR.jar If your JAR file has a different name than HelloJAR.jar, substitute the name appropriately. The output should appear identical to when you ran it from the Eclipse environment. Installing Eclipse University of Manitoba Tutorial 1 Page 26

27 When distributing the program, you must include both the application JAR file and the SWT jar file, and it is typically easiest to include the SWT DLL as well, rather than expecting the user to modify or know the PATH variable, or specify complicated command-line options. Importing an existing project If you have been provided with an Eclipse project from another source, you can import it into your workspace and begin using it right away, rather than creating a new project from the beginning. If you have been provided with the project in.zip format, first extract it to a location on your hard drive. This will become the working directory for the project, so ensure that the location you choose is where you intend to store the project while you work on it. For example, if you have been given a zip file called SampleProject.zip, containing a project called MyFirstProject and you wish to place the project folder in My Documents, extract the zip file into My Documents, and the folder MyFirstProject will be created containing all the files for the project. The folder name is always the same as the name of the project. If you have been given the project uncompressed, simply copy the project folder (along with its contents) it to a location on your hard drive. Ensure that the project folder contains a.project file. This is an XML data file used by Eclipse to store information about the project. It is used when Eclipse imports the project. Start Eclipse, and from the file menu, choose the Import option. The Import Wizard displays the following options. Installing Eclipse University of Manitoba Tutorial 1 Page 27

28 Choose Existing Project into Workspace, and hit Next. You must now specify the location of the project folder on your computer. Hit the browse button to bring up a Browse for Folder dialog. Select the project folder. The Project contents: text field should now display the location of the project folder, and the Project name: field should be filled in automatically with the project name, using information extracted from the.project file. In this example, we copied a project titled BasicWidgets into the Eclipse workspace directory. We then navigated to the project and selected the project. Installing Eclipse University of Manitoba Tutorial 1 Page 28

29 When you select Finish the project is now displayed in the workspace. Note that if the project you imported employs the SWT user interface libraries, you will need to configure Eclipse to locate and use them correctly. This was covered in Configuring Eclipse for programming with the SWT libraries. Opening and Closing Projects All projects that Eclipse is aware of are identified in the Package Explorer window. Projects that are open have a + beside the name, indicating that the project contents can be explored. Projects that are closed do not have a + beside the name. To open or close a project, select the project in the package explorer and then select Project Open Project or Close Project. Installing Eclipse University of Manitoba Tutorial 1 Page 29

30 In the workspace below, both the HelloWorld project and the BasicWidgets project are open and can be explored and run. To delete a project, right-click on the project name and then select Delete. Installing Eclipse University of Manitoba Tutorial 1 Page 30

31 The Debug Perspective When developing an application, it is often useful to be able to step through the program line by line, and examine how the code is actually working. It often makes it possible to quickly find and remove subtle bugs that are more difficult to locate when running the program as a whole. The Java development tools that ship with Eclipse include a fullfeatured set of Java debugging tools. These tools are usually located within the Debug Perspective, represented by the icon on the vertical toolbar on the left of the screen. An average debugging session will look something like the following, (assuming you haven t modified the default Debug perspective settings): The Debug view in the top-left displays a stack-trace. It lists the existing threads and the method that each thread is currently in. In the top-right there are four views stacked atop one another. The views are Variables, Breakpoints, Expressions and Display. The Variables view gives us access to a list of current variables and their values. The Breakpoints view lists the current breakpoints and their locations. The Expressions view allows us to enter watch expressions to be evaluated on the fly as we step through the code. Lastly, the Display view lets us enter code or expressions to be executed dynamically at the press of a button. We will return to look at these views in greater detail later in the tutorial. Installing Eclipse University of Manitoba Tutorial 1 Page 31

32 The three views on the bottom two thirds of the screen are familiar to us from an earlier tutorial, displaying the code, an outline of the code, and the console output from the current program. Basic Debugging To demonstrate how each component in the set of debugging tools works, we will look at a very simple Java class called DebugTest. It contains only one piece of data, and 3 methods to work with that data. Create a new Java class with name DebugTest, and enter the following code for it: public class DebugTest { int data = 0; public static void main(string[] args) { DebugTest test = new DebugTest(); test.setdata(5); test.incdata(); test.incdata(); int result = test.getdata(); System.out.println("Incremented result = " + result); public void setdata(int d) { data = d; public void incdata() { data++; public int getdata() { return data; To debug this program we must create a Launch Configuration as we did before when we simply wanted to run our programs. The only difference is that we execute it by choosing Debug from the Run menu, or pressing the down arrow on the debug button,, and selecting the desired program. If you are not currently in the Debug Perspective, the default behaviour of Eclipse is to automatically switch to it. If you Debug right now, your program will run straight through to completion, without stopping. The result will be the following: Incremented result = 7 This is not terribly useful to us, so what we must do is add breakpoints in our code. A breakpoint tells the Java debugger where we would like to halt execution of the code to Installing Eclipse University of Manitoba Tutorial 1 Page 32

33 take a closer look. There are several ways to create a breakpoint, the easiest of which is to click on the margin of the code editor beside the desired line of code. (The other two are pressing Ctrl-Shift-B, or choosing Add/Remove Breakpoint from the run menu, when the keyboard cursor is on the relevant line.) The blue circle that appears represents a breakpoint. If we Debug our program again (by pressing the bug icon or just F11), code execution will stop prior to execution of the selected line, and the line will be highlighted blue with an arrow in the margin. Stepping Through Code We can now step through the code one line at a time. We have several options, represented by buttons on the Debug view. We can Step Over a line of code with, Step Into a line of code with, or Step Return from a particular method using. These functions are also available from the Run menu. Step Over means that if the line contains a method call, you will not enter that method but instead execute the current line entirely and pause on the next line of code in the current method. If the code is paused as in the above image, you can use the Step Over button to proceed to the next line, containing the command test.incdata(). Step Into will do just the opposite, following execution into the method that has been called. It will pause on the first line of the called method. If execution is still paused on the first line containing test.incdata(), pressing Step Into will pause on the first line of incdata(), ie. data++. Notice that in the Debug view, the method incdata() method is now listed on the stack trace. Step Return will skip execution ahead to the point where the current method has returned, and again pause. If you have followed the above steps and execution is still paused in the incdata method, pressing Step Return will jump out of the method, and Installing Eclipse University of Manitoba Tutorial 1 Page 33

34 stop on the next line in the main method. incdata() will correspondingly disappear from the stack trace in the Debug view. (You may notice there is also a Step with Filters/Step Debug button,, which allows you to set filters to determine which methods your code should step into. For example, it would allow you to avoid stepping into 3 rd party libraries, while still stepping through your own code. You can modify the filters using the Java->Debug->Step Filtering preferences page.) To resume execution, we can press the Resume button represented by. Execution will continue normally, stopping again at any breakpoints that may occur later in the code. To stop a program at any point in the middle of its execution, the Terminate button,, is used. Once a program completes or is terminated, it will continue to be listed in the Debug view. Even if we run another program, this old information will continue to be listed. To get rid of it, press the Remove All Terminated Launches button, shown as. Examining The Data So far we have only looked at how to walk through the code, which may be useful in certain instances, but more often we would like to examine the state of the variables in our program as we proceed through it. To do this, we make use of the four views located in the top-right of the screen. The Variables view shows us the state of all the local variables active in the current method. If we run the sample program and stop it at any point in the main method, we will see listed two variables, test and args. test is the instance of our main class, and args is the array of strings representing the input to the method from the command line. Installing Eclipse University of Manitoba Tutorial 1 Page 34

35 Since test is a sub-class of Object, we can examine the data members it contains by clicking on the + beside its name. If any of the data members of test had been complex Objects, we could click the + beside their names, and continue recursively down the tree. An interesting example of this would be in debugging an implementation of a linked list, where each node contains references to other nodes. To examine the current state of the list we could simply follow the links. The bottom section of the Variables view shows the value of the currently selected item. In this case, data has a value of 7 at the current location. The next view is the Breakpoints view, which lists the current breakpoints. By doubleclicking on a breakpoint in the list you can see that line displayed in the Java editor. Another useful capability of the Breakpoint view is setting hit counts for breakpoints. If you right-click on a breakpoint in the list, and choose Hit Count you are prompted to enter a value. This value will determine how many times execution must pass that breakpoint before stopping. This is for debugging things like loops, in which you may only wish to see what is happening on the 421 st iteration, for example. Installing Eclipse University of Manitoba Tutorial 1 Page 35

36 The Expressions view allows you to specify particular expressions to evaluate on each step in order to see what is happening in your code. The expression may just be the name of a variable, or it can be a complex arithmetic expression. It can even contain method calls, like test.getdata(). To add an expression, right-click on the view and choose Add Java Watch Expression. Enter an expression, and it will appear in the list along with its current value. If a particular variable is not in scope, its value will be displayed as <error(s) during the evaluation>. Closely related to the Expressions view is the Display view. It allows you to enter an expression or statement directly into it and run/evaluate it on command. To do so, simply click in the Display view, and type the expression or statement. Then select the entire expression and press the Display Result of Evaluating Selected Text button,, on the Display view. This will run the code, and display the return value (if there is one). Alternatively, if you press the left-most button ( Inspect Result, value of the expression will be displayed in the Expressions view. ), the current By right-clicking on it and choosing Convert to Watch Expression it will become a new watch expression and get updated as you continue through the code. That rounds out the list of basic debugging facilities offered by Eclipse s Java Development tools. Although they are very straightforward, they should simplify a great deal of the debugging tasks that an average developer is faced with. Installing Eclipse University of Manitoba Tutorial 1 Page 36

37 Eclipse and Linux Installing Eclipse under Linux is almost identical to the Windows install. In this section, we examine the differences between the Windows and the Linux installs. In the following examples, Eclipse 2.1 was installed and run on SuSE Linux 8.1 (Office Desktop version) running the kernel. Eclipse was installed in /opt to make it available to all users of the machine. The Java JRE was used to run the programs. After downloading and unzipping the GTK version of Eclipse, the Eclipse folder has the following contents. After installing the Motif version of Eclipse, the folder has the following contents. Installing Eclipse University of Manitoba Tutorial 1 Page 37

38 If Eclipse is installed in a public directory, such as /opt, ensure that users have the appropriate permissions to run the system. The following script can be used to run Eclipse. export LD_LIBRARY_PATH=/opt/eclipse-gtk-2.1/eclipse:$LD_LIBRARY_PATH cd /opt/eclipse-gtk-2.1/eclipse./eclipse -ws gtk The workspace is placed either in the Eclipse directory or in /home/username/workspace directory (it appears to depend on the permissions defined for the Eclipse directory). If necessary, the data parameter can be included to indicate that the workspace is to be placed in a different directory. export LD_LIBRARY_PATH=/opt/eclipse-gtk-2.1/eclipse:$LD_LIBRARY_PATH cd /opt/eclipse-gtk-2.1/eclipse./eclipse -ws gtk -data /home/user/gtk/workspace When Eclipse with GTK is first run, the Welcome screen is displayed. The following script is used to run the Motif version of Eclipse. export LD_LIBRARY_PATH=/opt/eclipse-motif-2.1/eclipse:$LD_LIBRARY_PATH cd /opt/eclipse-motif-2.1/eclipse./eclipse -ws motif Installing Eclipse University of Manitoba Tutorial 1 Page 38

39 Similarly, when Eclipse with Motif is first run, the Welcome screen is displayed. A new project is created in exactly the same manner as described earlier in the Windows section. The simple HelloWorld program generates the following output on GTK. The simple HelloWorld program generates the following output on Motif. Installing Eclipse University of Manitoba Tutorial 1 Page 39

40 As noted in the Windows section, when SWT widgets are used in an application, the swt.jar library must be identified on the Java Build Path. As shown in the following screenshot, when SWT widgets are included in a GTK program, the swt-pi.jar file must also be included on the Java Build Path. Similarly, when Motif is used, the swt.jar file must be included. Installing Eclipse University of Manitoba Tutorial 1 Page 40

41 When SWT widgets are included in an application, the appropriate run-time libraries must be identified to Eclipse; if these libraries are not available, a run-time error is generated. The run-time libraries are identified in the VM arguments section of the Run command: -Djava.library.path=/opt/eclipse-gtk-2.1/eclipse/plugins/org.eclipse.swt.gtk_2.1.0/os/linux/x86 The Motif run-time libraries are identified in the same manner: -Djava.library.path=/opt/eclipse-motif-2.1/eclipse/plugins/org.eclipse.swt.motif_2.1.0/os/linux/x86 Finally, once everything has been defined, the Hello World program runs correctly. Installing Eclipse University of Manitoba Tutorial 1 Page 41

42 Creating and running a jar file Generating an executable jar file for a Linux SWT application is almost identical to the techniques described in the Windows section. In this section, we identify the differences that exist between Linux and Windows. As was mentioned in the Windows section, the swt.jar file (for GTK, the swt.jar and swtpi.jar files) must be available at run-time. These files may be made available by copying them to the Sun s Java jre/lib/ext directory. Alternatively, the two files could be placed in the directory that will contain the jar file. Use the Export command as was described in the Windows section. If the swt.jar file is to be placed in the Java ext directory, the following manifest file may be used. Manifest-Version: 1.0 Main-Class: SWTHello If the swt.jar file is to be included in the same directory as the SWT application, the following manifest file may be used. Note that the swt-pi.jar is required only for the GTK window system. For this manifest file to work, the swt.jar (and swt-pi.jar) must be copied to the directory in which the jar file is stored. Manifest-Version: 1.0 Main-Class: SWTHello Class-Path: swt.jar swt-pi.jar If it is preferred that the files not be copied to the jar directory, then the following manifest file may be used to specify the location of the jar files at run-time. Note that the file names may be split over multiple lines, simply ensure that there is a blank in column 1 of the continued line(s). Manifest-Version: 1.0 Main-Class: SWTHello Class-Path: file:/opt/eclipse-gtk-2.1/eclipse/plugins/org.eclipse.swt.gtk_2.1.0/ws/gtk/swt.jar file:/opt/eclipse-gtk-2.1/eclipse/plugins/org.eclipse.swt.gtk_2.1.0/ws/gtk/swt-pi.jar Once the jar file has been built, it may be run from the command prompt with the following script for GTK: export LD_LIBRARY_PATH=/opt/eclipse-gtk-2.1/eclipse/plugins/org.eclipse.swt.gtk_2.1.0/os/linux/x86/:$LD_LIBRARY_PATH cd workspace/helloworld java -jar HelloWorld.jar Installing Eclipse University of Manitoba Tutorial 1 Page 42

43 or with the following GTK script: cd workspace/helloworld java -Djava.library.path=/opt/eclipse-gtk-2.1/eclipse/plugins/org.eclipse.swt.gtk_2.1.0/os/linux/x86 - jar HelloWorld.jar If you are running with Motif, two sets of run-time routines are required: those in the eclipse folder and those in the plugins os folder. To simplify running the jar, we copied the 3 run-time files from the plugins os folder to the top level Eclipse folder. The contents of the folder are shown below. The Motif jar file can now be run with the following script: export LD_LIBRARY_PATH=/opt/eclipse-motif-2.1/eclipse/:$LD_LIBRARY_PATH cd workspace/helloworld java -jar HelloWorld.jar To avoid copying the run-time routines to the same directory, the export command that sets the library path could be expanded to include both libraries. When you are building a jar file for the first time and making changes to the manifest file at the same time, you may receive a jar message that indicates the resources are not in sync. Installing Eclipse University of Manitoba Tutorial 1 Page 43

44 This message is not particularly self-explanatory but the problem can be fixed by refreshing the current project. To do this, right-click on the project name and select Refresh from the menu. This should eliminate the problem. We encountered a few minor problems when running Eclipse with Linux. With SuSE Linux/KDE, the accelerator combination for Run Last Launched (cntl-f11) did not work, although it did work correctly on the same machine when running Windows XP and when running Linux/Gnome. The Debug Last Launched (F11) did work correctly on SuSE Linux/KDE. Installing Eclipse University of Manitoba Tutorial 1 Page 44

45 Also, when running with Gnome, the SWTHelloWorld window was compacted when the application was run and, as a result, it was easy to miss the window on the desktop. Clicking on the bottom-right corner and dragging the window makes the window visible. Installing Eclipse University of Manitoba Tutorial 1 Page 45

46 Summary This document contains a brief introduction to installing and configuring Eclipse so that Java programs can use the SWT. We have attempted to keep the configuration details simple to avoid confusing the first-time user. We have deliberately not included a comprehensive description of the Eclipse workbench. For more information on the workbench, a document titled The Eclipse Workbench User's Guide is available at: The Eclipse Faq is currently available at: As you become more familiar with the workbench, you will likely want to use accelerator keys instead of the menus for frequently used operations. A list of the accelerator keys is available at: Installing Eclipse University of Manitoba Tutorial 1 Page 46

47 Basic SWT Widgets 1, 2 by Shantha Ramachandran, University of Manitoba, Winnipeg, Manitoba, Canada Last revised: June 4, 2003 Overview: In this document, we describe the basic SWT (Standard Widget Toolkit) widgets. Our focus is on developing Java applications that use the SWT, not on developing plugins to extend the Eclipse workbench. If you have not already run an SWT-based application using the Eclipse workbench, you should review the information on installing Eclipse and setting up the SWT libraries in the previous document, Installing Eclipse. Widget Structure: To create an application that uses SWT widgets, you need to start by importing the following packages: org.eclipse.swt.*; org.eclipse.swt.widgets.*; It is necessary to create a Display and a Shell to hold the SWT widgets: Display display = new Display(); Shell shell = new Shell(display); A display is an object that contains all GUI components. A display is not actually visible but the components added to a display are visible. Typically, only one display is created for an application. A shell is a window within the application. There may be any number of shells created for an application, with shells being at the top level (attached to a display) or shells being attached to other shells. 1 This work was funded by an IBM Eclipse Innovation Grant. 2 Shantha Ramachandran and David Scuse Basic SWT Widgets University of Manitoba Tutorial 2 Page 1

48 The properties of the SWT widgets are initialized and/or modified in the same manner as Swing widgets. You can set the size of the shell: shell.setsize(100,100); Finally, you need to open the shell and run an event loop. This event loop is required for the shell to visible on the screen. You can place it after any code you have initializing widgets on the shell. When the shell is closed, the display must be disposed. shell.open(); while(!shell.isdisposed()){ if(!display.readanddispatch()) display.sleep(); display.dispose(); Now, you are ready to add any widgets to your shell. We will not use a layout manager for now, as creating widgets with a layout manager is a little more complicated. The following examples all deal with placing widgets on a shell with no layout. Label A label is a collection of characters that can not be modified by the user (although the characters can be modified by the programmer). To place a label on your shell, use the following code: Label label1 = new Label(shell, SWT.BORDER); The different styles of labels are BORDER, CENTER, LEFT, RIGHT, WRAP and SEPARATOR. The separator style is a special kind of label that draws a line separating your other widgets. The styles that can be added for a separator are HORIZONTAL, VERTICAL, SHADOW_IN, SHADOW_OUT and SHADOW_NONE. The following code creates five labels, two of which are separators. The first text label has a border, the second is a normal label, and the third has a colored background that was set using the setbackground() method. The two separators in the example are horizontal, but the first has a shadow style applied to it. Basic SWT Widgets University of Manitoba Tutorial 2 Page 2

49 Label label1 = new Label(shell, SWT.BORDER); label1.settext("see no evil"); label1.setsize(100,20); label1.setlocation(30,30); Label sep1 = new Label(shell, SWT.SEPARATOR SWT.HORIZONTAL SWT.SHADOW_IN); sep1.setbounds(30,60,100,20); Label label2 = new Label(shell, SWT.NONE); label2.settext("hear no evil"); label2.setsize(100,20); label2.setlocation(30,90); Label sep2 = new Label(shell, SWT.SEPARATOR SWT.HORIZONTAL); sep2.setbounds(30,120,100,20); Label label3 = new Label(shell, SWT.NONE); label3.setsize(100,20); label3.setlocation(30,150); label3.setbackground(new Color(display,200,111,50)); label3.settext("speak no evil"); This results in the following window: Text A text widget contains text that can normally be modified by the user. To place a text widget on your screen, use the following code: Text text1 = new Text(shell, SWT.BORDER); Basic SWT Widgets University of Manitoba Tutorial 2 Page 3

50 The styles that are supported by Text are BORDER, H_SCROLL, V_SCROLL, MULTI, SINGLE, READ_ONLY and WRAP. The text widget has some interesting properties that can be set. If your text is editable, you can set the maximum number of characters that can be typed: text1.settextlimit(30); You can also create password text boxes by using the setechochar() method. The argument for this method is the character that is to be displayed in the text. The correct string will still be in the text, but will only be viewed as a sequence of a specified character: text2.setechochar('*'); The following code creates three text widgets. The first one has a 30 character text limit. The second one displays all text as a series of asterisks, much like a password field. The final text has used the seteditable() method to make the control read only. Another way to accomplish this would be to give it the style SWT.READ_ONLY. Try running the following code and typing in the text widgets: Text text1 = new Text(shell, SWT.BORDER); text1.settext("type something in here"); text1.setbounds(10,10,200,20); text1.settextlimit(30); Text text2 = new Text(shell, SWT.NONE); text2.setechochar('*'); text2.setbounds(10,50,200,20); text2.settext("password"); Text text3 = new Text(shell, SWT.BORDER SWT.H_SCROLL SWT.V_SCROLL); text3.setbounds(10,90,200,100); text3.seteditable(false); text3.settext("bet you can't type in here"); Basic SWT Widgets University of Manitoba Tutorial 2 Page 4

51 This produces the following window: Button A button is a widget that is clicked by the user in order to initiate some processing. To place a button on the shell, use the following code: Button button1 = new Button(shell,SWT.PUSH); You can replace SWT.PUSH with any of the button types that SWT supports. This includes PUSH, CHECK, RADIO, TOGGLE and ARROW. You can also use the styles FLAT, BORDER, LEFT, RIGHT and CENTER with one of these types. To set the text of the button, use the settext() method: button1.settext("hello"); In order for the button to be visible on the screen, you need to set the size and the location of the button. Alternatively, you can set the bounds of the button and both the size and the location will be set at once. button1.setlocation(0,0); button1.setsize(100,20); You can also set the style, background, image and more by using set methods. To add an event handler to your button, you first need to import the events package: import org.eclipse.swt.events.*; Basic SWT Widgets University of Manitoba Tutorial 2 Page 5

52 A basic event handler for the button is a selection event handler. This 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 following code: button1.addselectionlistener(new SelectionAdapter() { ); public void widgetselected(selectionevent e) { System.out.println("Button1 was clicked"); Here is a small sample that incorporates all the code seen above. It creates a button which, when clicked, will print Button was clicked to the console, an arrow button, and a button with more than one style - toggle and flat. Button button1 = new Button(shell,SWT.PUSH); button1.settext("click me"); button1.setlocation(0,0); button1.setsize(100,20); button1.addselectionlistener(new SelectionAdapter() { public void widgetselected(selectionevent e) { System.out.println("Button1 was clicked"); ); Button button2 = new Button(shell, SWT.ARROW); button2.setsize(20,20); button2.setlocation(250,200); Button button3 = new Button(shell, SWT.FLAT SWT.TOGGLE); button3.setsize(50,50); button3.setlocation(0,150); The following window is displayed: Basic SWT Widgets University of Manitoba Tutorial 2 Page 6

53 List A list is a widget that contains a collection of items; the user may select an item from the list. To place a list on your screen, use the following code: List list1 = new List(shell, SWT.MULTI); The different styles that a list supports are BORDER, H_SCROLL, V_SCROLL, SINGLE and MULTI. To add items to a list, you can use the setitems() method, or the add() method. In the following example, two lists are created. The first list uses the H_SCROLL style to create a horizontal scrollbar within the list. The second one uses a MouseListener to respond to MouseDown and MouseUp events. The MouseListener works in a similar fashion to the SelectionListener. A MouseAdapter is created with one of or both of mouseup() and mousedown() methods. This is the code that is necessary: list2.addmouselistener(new MouseAdapter() { public void mousedown(mouseevent e) { System.out.println(list2.getSelection()[0] +" wins"); public void mouseup(mouseevent e) { System.out.println("Try again!"); ); Note that list2 must be declared as final in order to use it within the adapter: List list1 = new List(shell, SWT.MULTI SWT.H_SCROLL); list1.setitems(new String[] {"Strawberry","Banana","Apple"); list1.add("pickle"); list1.setbounds(0,0,60,100); final List list2 = new List(shell, SWT.SINGLE SWT.BORDER); list2.setitems(new String[] {"Rock","Paper","Scissors"); list2.setbounds(110,0,50,50); list2.addmouselistener(new MouseAdapter() { public void mousedown(mouseevent e) { System.out.println(list2.getSelection()[0] +" wins"); public void mouseup(mouseevent e) { System.out.println("Try again!"); ); Basic SWT Widgets University of Manitoba Tutorial 2 Page 7

54 The following window is displayed: Combo A combo widget allows the user to select an item from a collection of items. The user may also type a value into the combo widget. To place a combo box on the shell, use the following code: Combo combo1 = new Combo(shell,SWT.DROP_DOWN SWT.READ_ONLY); The styles that are supported by Combo are BORDER, DROP_DOWN, READ_ONLY and SIMPLE. More than one style can be used at a time, as in the above code. To add items to a Combo, use the setitems() method. This takes a string array as an argument. combo1.setitems(new String[] {"One","Two","Three"); Use the select() method to select one of the list items. This method takes an integer argument - the index of the item to be selected. The following example creates three Combos. The first is a drop down list whose location and size are set. The second is a simple Combo whose location and size are set at one time using the setbounds() method. The third is a Combo with no items. Combo combo1 = new Combo(shell, SWT.DROP_DOWN SWT.READ_ONLY); combo1.setitems(new String[] {"One","Two","Three"); combo1.select(0); combo1.setlocation(0,0); combo1.setsize(100,20); Combo combo2 = new Combo(shell, SWT.SIMPLE); combo2.setitems(new String[] {"Red","Green","Blue","Yellow"); combo2.setbounds(50,50,200,150); combo2.select(1); Combo combo3 = new Combo(shell, SWT.DROP_DOWN); combo3.setlocation(200,0); combo3.setsize(50,50); Basic SWT Widgets University of Manitoba Tutorial 2 Page 8

55 The following is window is displayed: Composite A composite is a widget that can contain other widgets. Widgets are placed inside a composite in the same manner that widgets are placed on a shell. The position of each widget inside a composite is relative to the composite, so if the composite is moved on the shell, the widgets inside the composite retain their relative positions. To place a composite on your shell, use the following code: Composite composite1 = new Composite(shell,SWT.BORDER); The styles supported by composites are BORDER, H_SCROLL and V_SCROLL. You can set properties of the composite, like background colour, but you cannot set a text value. Label label = new Label(composite1,SWT.NONE); The following code is an example of placing 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: import org.eclipse.swt.graphics.*; Color mycolor = new Color(display, 0, 0, 0); Note that if you do not give a composite a border or a background, you will not be able to distinguish it from the rest of the shell. The second composite exists within the first. It has horizontal and vertical scroll bars, and a list within the composite: Composite composite1 = new Composite(shell,SWT.BORDER); composite1.setbounds(10,10,270,250); composite1.setbackground(new Color(display,31,133,31)); Label label = new Label(composite1,SWT.NONE); Basic SWT Widgets University of Manitoba Tutorial 2 Page 9

56 label.settext("here is a green composite"); label.setbounds(10,10,200,20); Composite composite2 = new Composite(composite1,SWT.H_SCROLL SWT.V_SCROLL); composite2.setbounds(10,40,200,200); List list = new List(composite2,SWT.MULTI); for (int i=0; i<50; i++) { list.add("item " + i); list.setsize(300,300); This produces the following screen: Group A group is also a widget that can contain other widgets. A group is surrounded by a border and may, optionally, contain a title. As with composites, the position of each widget inside a group is relative to the group, so if the group is moved on the shell, the widgets inside the group retain their relative positions. To add a group to your screen, use the following code: Group group1 = new Group(shell, SWT.BORDER); The styles that are supported by group are BORDER, SHADOW_ETCHED_IN, SHADOW_ETCHED_OUT, SHADOW_IN, SHADOW_OUT and SHADOW_NONE. You can set all the standard properties for a group, such as size, location, background, and more. However, the principal use of a group is to separate other controls into sections. A group is a subclass of composite, and works in very much the same way. It has additional functionality though, such as setting the text: group1.settext("group 1"); Basic SWT Widgets University of Manitoba Tutorial 2 Page 10

57 You can place a control onto a group in the same way you would add a control to a shell or a composite: Button button = new Button(group1, SWT.PUSH); The following example only uses one group on the main shell, but has a second group embedded within the first group. Since a group is a control as well as a composite, this is allowable. You can have many nested groups to arrange numerous controls on a screen: Group group1 = new Group(shell, SWT.BORDER); group1.setbounds(30,30,200,200); group1.settext("group 1"); Button button = new Button(group1, SWT.PUSH); button.setbounds(10,20,80,20); button.settext("i'm in a group"); Label label = new Label(group1, SWT.NONE); label.setbounds(10,50,80,20); label.settext("so am I!!"); Group group2 = new Group (group1, SWT.NONE); group2.setbounds(10,100,150,50); group2.setbackground(new Color(display,233,20,233)); group2.settext("i'm a group inside a group"); Button button2 = new Button(group2, SWT.PUSH); button2.setbounds(10,20,50,20); button2.settext("twice.."); This results in the following window: Basic SWT Widgets University of Manitoba Tutorial 2 Page 11

58 Running under Linux: The widgets shown in this document were also run under Linux (GTK and Motif). Other than some slight differences in appearance, we have not found any differences in behaviour. GTK Motif Events: In the earlier sections of this document, we introduced the Eclipse event structure by defining listeners for buttons and a few other simple events. We now describe the Eclipse event structure in more detail and create listeners for a variety of common events. To capture events in SWT, you need to add listeners to your controls. Then when the event corresponding to the listener occurs, the listener code will be executed. In order to capture events in SWT, you need to do two things. First, you create a listener specific to the event that you wish to capture. There is an interface for each listener that you can use (ie. SelectionListener). There is also a class that will provide you with the event information (ie. SelectionEvent). Within the listener that you create, you must implement the methods defined in the interface. SelectionListener listener = new SelectionListener() { public void widgetselected(selectionevent arg0) { System.out.println("Button Selected"); public void widgetdefaultselected(selectionevent arg0) { ; Basic SWT Widgets University of Manitoba Tutorial 2 Page 12

59 If there is more than one method, you can create an adapter instead (ie. SelectionAdapter). An adapter implements the interface with empty methods so that you do not have to define 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. In this case, we can create an adapter instead, and only implement the widgetselected() method. SelectionAdapter adapter = new SelectionAdapter() { public void widgetselected(selectionevent arg0) { System.out.println("Button Selected"); ; The second thing you need to do is add the listener to your widget. Each control has methods to add listeners (ie. addselectionlistener()). You pass your listener to this method, and you are all set to capture events. Button button = new Button(shell, SWT.PUSH); button.addselectionlistener(listener); Or, in our case, we could have also used: button.addselectionlistener(adapter); Now that we know how to add a listener to a widget, we will go over the more common types of listeners. The most common type of listener is the selection listener, which we have just seen. Some other important ones include key listeners and mouse listeners. Key Listener The KeyListener has two methods, keypressed and keyreleased, whose functions are obvious. The event object is KeyEvent. Because there are two methods, there is also a KeyAdapter you can use to implement only one of the methods. The KeyEvent is the more interesting feature of capturing key events. In most cases, if you are using a key listener, you wish to know which key was pressed. The KeyEvent has a property called character, which stores which character was just pressed. You can access this character value using e.character (where e is the KeyEvent parameter). You can also access the key code and state mask of the key that was pressed. The key codes for special keys are constants in the SWT library, like SWT.CTRL for the control key and SWT.CR for the carriage return key. The state mask indicates the status of the keyboard modifier keys. The example at the end of this section demonstrates how you can use the state mask. Basic SWT Widgets University of Manitoba Tutorial 2 Page 13

60 The following example demonstrates using the key pressed and key released methods in the key listener. We attach the key listener to a basic text widget and a key event is generated every time you type in the text. In the key pressed method, we check to see if the key pressed 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 key released method, we check to see 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: Text text = new Text(shell, SWT.MULTI SWT.BORDER); text.setbounds(10,10,100,100); text.addkeylistener(new KeyListener() { public void keypressed(keyevent e) { String string = ""; switch (e.character) { case 0: string += " '\\0'"; break; case SWT.BS: string += " '\\b'"; break; case SWT.CR: string += " '\\r'"; break; case SWT.DEL: string += " DEL"; break; case SWT.ESC: string += " ESC"; break; ); case SWT.LF: default: System.out.println (string); string += " '\\n'"; break; string += " '" + e.character +"'"; break; public void keyreleased(keyevent e) { if (e.statemask == SWT.CTRL && e.keycode!= SWT.CTRL) System.out.println("Command can execute here"); Try this code out and see what kind of results you get from pressing various keys. Note that if we used a KeyAdapter instead of a KeyListener, we would have only had to implement one of keypressed and keyreleased. Mouse Listeners There are three types of mouse listeners; MouseListener, which tracks pressing the mouse, MouseMoveListener, which tracks when the mouse is being moved, and MouseTrackListener, which tracks where the mouse is in relation to the control. We will go over all three of these listeners. Since we are dealing with events, it is not possible to show the results here, so make sure you try out the code, to see what kind of results you get. Basic SWT Widgets University of Manitoba Tutorial 2 Page 14

61 MouseListener The MouseListener has three methods, mousedown, mouseup and mousedoubleclick. The functions of these methods are stated in the names. Because there are three methods in this listener, a MouseAdapter is available. The class that contains information on the event is MouseEvent. The fields in MouseEvent which are unique to the MouseListener are x, y, statemask and button. The button property returns the number of the button that was pressed or released. So the first button on the shell would return a value of 1, the second would return 2, and so on. The x and y properties return the location coordinates of the mouse at the time of the event. The statemask property returns the state of the keyboard modifier keys at the time of the event. The following example has two MouseAdapters. One of the adapters implements the mouseup and mousedown methods. This adapter is attached to two different buttons. We can do this by first creating the adapter, then adding it to whichever widgets need to use it. We find the number of the button that has been pressed, and also the coordinates of the mouse when it is both pressed and released. The other adapter implements the mousedoubleclick method. It opens a new window when the double click event it created on the Label: Button button = new Button(shell, SWT.PUSH); button.settext("push Me"); button.setbounds(10,10,60,20); Button button2 = new Button(shell, SWT.PUSH); button.settext("push Me Too"); button.setbounds(100,10,60,20); MouseAdapter mouseadapter = new MouseAdapter() { public void mousedown(mouseevent e) { System.out.println("Button "+e.button+" pressed"); System.out.println("Mouse pressed at (" + e.x + ", + e.y + ")"); public void mouseup(mouseevent e) { System.out.println("Mouse released at (" + e.x + "," + e.y + ")"); ; button.addmouselistener(mouseadapter); button2.addmouselistener(mouseadapter); Label label = new Label(shell, SWT.NONE); label.settext("double Click Me"); label.setbounds(10,40,100,20); label.addmouselistener(new MouseAdapter() { Basic SWT Widgets University of Manitoba Tutorial 2 Page 15

62 ); public void mousedoubleclick(mouseevent e) { Shell shell2 = new Shell(display); shell2.setsize(100,100); Label label2 = new Label(shell2,SWT.NONE); label2.settext("hello New Window!"); label2.setbounds(0,50,100,20); shell2.open(); Try this code out. 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, you will see the different coordinates that your mouse was pressed and released at. Mouse Move Listener The MouseMoveListener has one method, mousemove. This method is invoked when the mouse is moved over the control onto which it is attached. The event generated is a MouseEvent again. See the example at the end of this section. Mouse Track Listener The MouseTrackListener has three methods, mouseenter, mouseexit and mousehover. The mouseenter method is called when the mouse enters into the area covered by the control to which it is attached. Similarly, the mouseexit method is called when the mouse exits said region. The mousehover method is executed when the mouse hovers over the control to which it is attached. The following example illustrates how to use both the mouse move listener and the mouse track listener. The first canvas has a mouse move listener attached to it. When you move the mouse over top of the canvas, the colour of the canvas changes. The second canvas has a mouse track listener attached to it. When your mouse enters over top of the canvas, a number is displayed in the canvas. Each time you hover your mouse over the canvas, the number is increased. When the mouse leaves the area of the canvas, the number disappears and starts at zero again when the mouse re-enters the area. int count1=0, count2=0; final Canvas canvas = new Canvas(shell, SWT.BORDER); canvas.setbounds(10,10,100,100); Canvas canvas2 = new Canvas(shell, SWT.BORDER); canvas2.setbounds(150,150,100,100); final Text text = new Text(canvas2, SWT.READ_ONLY); text.setbounds(40,30,20,20); Basic SWT Widgets University of Manitoba Tutorial 2 Page 16

63 MouseMoveListener mousemove = new MouseMoveListener() { public void mousemove(mouseevent e) { Color color = canvas.getbackground(); color.dispose(); canvas.setbackground(new Color(display,count1,0,255)); count1++; count1 = count1%255; ; canvas.addmousemovelistener(mousemove); MouseTrackListener mousetrack = new MouseTrackListener() { public void mouseenter(mouseevent arg0) { text.settext(integer.tostring(count2)); public void mouseexit(mouseevent arg0) { text.settext(""); count2 = 0; public void mousehover(mouseevent arg0) { count2++; text.settext(integer.tostring(count2)); ; canvas2.addmousetracklistener(mousetrack); Note that in order to change a control within a listener, it must be declared as a final variable. Run this code and see what kind of results you get by generating mouse events on the controls. Text Listeners There are a couple of listeners that are useful when using Text widgets. These are the ModifyListener and the VerifyListener. The ModifyListener is called when text is modified, and the VerifyListener is called before text is modified. This one can be used to verify that the new values being entered are valid. We will briefly go over both of these listeners. ModifyListener The ModifyListener has one method, modifytext. The event object is a ModifyEvent. This event is similar to a TypedEvent, and has fields such as time and widget. Basic SWT Widgets University of Manitoba Tutorial 2 Page 17

64 The ModifyListener can be used when we need to be notified if text has been changed. The modifytext method is called every time a character is modified. See the example at the end of this section. VerifyListener The VerifyListener has one method, verifytext. The event object is a VerifyEvent. This event has all the properties of a TypedEvent and a KeyedEvent, as well as the fields start, end, doit and text. The start and end properties indicate the range of text which is about to be modified. The text variable indicates the new text to which your text is being changed. The doit flag indicates whether or not we should complete the action that triggered the event. We can use the VerifyListener to check and make sure certain characters can be entered in specific fields. In the following example, we check to see if the user is entering an asterisk in the text. If so, the action is cancelled. Notice that no matter how many times the * key is pressed, no asterisks will appear in the text. Text text = new Text(shell, SWT.MULTI SWT.WRAP); text.setbounds(10,10,200,100); text.settext("here is some sample text"); text.addmodifylistener(new ModifyListener() { public void modifytext(modifyevent e) { System.out.println("Modified at " + e.time); ); text.addverifylistener(new VerifyListener() { public void verifytext(verifyevent e) { if (e.text.equals("*")) { System.out.println("Cannot type *"); e.doit = false; ); Focus Listeners This section deals with FocusListener and TraverseListener. The FocusEvent is generated when a widget receives focus, by any means. A TraverseEvent is generated when a widget gains focus by means of traversal. We will cover both kinds of event handlers. FocusListener The FocusListener has two methods, focusgained and focuslost. They are called at obvious times. The event generated is a FocusEvent. This event has all the properties of a TypedEvent. See the example at the end of this section for more details. Basic SWT Widgets University of Manitoba Tutorial 2 Page 18

65 TraverseListener The TraverseListener has one method, keytraversed. This is called when the widget the handler is attached to is traversed by a traversal method, such as tabs or up and down arrows. The event generated is a TraverseEvent. Some useful properties of this event object are detail and doit. The doit property is the same as for the VerifyListener; it sets a flag indicating whether the event should continue. The detail property indicates what kind of traversal generated the event. These traversals can all be referred to by using SWT.TRAVERSE_XXXX. In the following example, you can see we compare the detail in the TraverseEvent with SWT.TRAVERSE_TAB_PREVIOUS. If the traversal was a previous tab, we cancel the action. Button b1 = new Button(shell, SWT.PUSH); Button b2 = new Button(shell, SWT.PUSH); Button b3 = new Button(shell, SWT.PUSH); Button b4 = new Button(shell, SWT.PUSH); Button b5 = new Button(shell, SWT.PUSH); Button b6 = new Button(shell, SWT.PUSH); b1.setbounds(10,10,50,50); b2.setbounds(100,10,50,50); b3.setbounds(200,10,50,50); b4.setbounds(10,100,50,50); b5.setbounds(100,100,50,50); b6.setbounds(200,100,50,50); b1.settext("1"); b2.settext("2"); b3.settext("3"); b4.settext("4"); b5.settext("5"); b6.settext("6"); FocusListener focuslistener = new FocusListener() { public void focusgained(focusevent e) { System.out.println(e.widget + " has focus"); public void focuslost(focusevent e) { System.out.println("And now has lost it."); ; Basic SWT Widgets University of Manitoba Tutorial 2 Page 19

66 TraverseListener traverselistener = new TraverseListener() { public void keytraversed(traverseevent e) { if (e.detail == SWT.TRAVERSE_TAB_PREVIOUS) { System.out.println("You can't go back!"); e.doit = false; System.out.println(e.widget + " was traversed"); ; b1.addfocuslistener(focuslistener); b4.addtraverselistener(traverselistener); b4.addfocuslistener(focuslistener); b6.addtraverselistener(traverselistener); Basic Widgets Project A project that contains the examples used in this document is available in a zip file format. In order to make it possible to run each demo from a main shell, the instructions used to create each demo had to be modified because Eclipse does not permit an application to create more than one display. To run a demo program by itself, a display is created at the beginning of the run method. public class ButtonDemo { public static void main(string[] args) { ButtonDemo bd = new ButtonDemo(); bd.rundemo(); public void rundemo() { Display display = new Display(); Shell shell = new Shell(display); If the method may be called either by the demo program itself or by an external supervisory routine, the following changes must be made to the program structure. public class ButtonDemo { public static Display mydisplay; public static boolean internalcall = false; public static void main(string[] args) { internalcall = true; mydisplay = new Display(); ButtonDemo bd = new ButtonDemo(); bd.rundemo(mydisplay); public void rundemo(display display) { mydisplay = display; Shell shell = new Shell(display); Basic SWT Widgets University of Manitoba Tutorial 2 Page 20

67 Now, the method may be called by an external supervisory routine, as shown below. Summary: We have examined only the basic widgets, some of their common properties, and the basic event structure in this document. For more information on each widget, review the Eclipse API documentation at: We will examine some of the more sophisticated widgets in subsequent documents. Basic SWT Widgets University of Manitoba Tutorial 2 Page 21

68 Advanced SWT Widgets 1, 2 by Shantha Ramachandran, Christopher Batty, and Weichi Truong, University of Manitoba, Winnipeg, Manitoba, Canada Last revised: February 20, 2004 Overview: In this document, we describe some of the more advanced SWT widgets. Tables To add a table to your shell, use the following code: Table table1 = new Table(shell, SWT.BORDER); The styles that can be used are BORDER, H_SCROLL, V_SCROLL, SINGLE, MULTI, CHECK (this style creates a check box column as the first column), FULL_SELECTION and HIDE_SELECTION. There are two options you can set for a table. You can decide whether the lines will be visible on the table. You can also decide whether the headers for the columns will be visible. Both of these properties are defaulted to false. The following lines of code will set these properties: table1.setlinesvisible(true); table1.setheadervisible(true); Now, the table is created, but as a default it only has one column. If you try to add any items to the table, only the first field of the item will be displayed in the table. In order to display all the fields you want, you need to define TableColumns. TableColumns To add table columns to your table, use the following code: 1 This work was funded by an IBM Eclipse Innovation Grant. 2 Shantha Ramachandran, Christopher Batty, and David Scuse Advanced SWT Widgets University of Manitoba Tutorial 3 Page 1

69 TableColumn name = new TableColumn(table1,SWT.LEFT); The styles that are allowed are LEFT, RIGHT and CENTER. You should also set at least the width of the column, and a name if you are going to display the headers: name.settext("name"); name.setwidth(50); After creating the columns for your table, you are now ready to add TableItems. TableItems To add a table item to your table, use the following code: TableItem item1 = new TableItem(table1,SWT.NONE); There are no styles for a TableItem, so you can use SWT.NONE, which is 0. To set the text for an item, you can use the settext() method: item1.settext(new String[] {"Sarah","15","390 Sussex Ave"); This will create a TableItem with fields in the order that you defined them. If you wish to define one field at a time, you can use the settext(int, string) method which places the text into a specific field in the record. After creating TableColumns and TableItems, your table will be fully populated. Now we will look at three simple examples of tables and see the different styles that can be used. The first example has a border, fixed size columns, with different horizontal alignments: Table table1 = new Table(shell, SWT.BORDER); table1.setbounds(10,10,270,60); table1.setlinesvisible(true); TableColumn name = new TableColumn(table1,SWT.LEFT); name.settext("name"); name.setwidth(50); TableColumn age = new TableColumn(table1,SWT.RIGHT); age.settext("age"); age.setwidth(30); TableColumn address = new TableColumn(table1,SWT.LEFT); address.settext("address"); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 2

70 address.setwidth(200); TableItem item1 = new TableItem(table1,SWT.NONE); item1.settext(new String[] {"Sarah","15","390 Sussex Ave"); TableItem item2 = new TableItem(table1,SWT.NONE); item2.settext(new String[] {"Joseph","56","7 Yourstreet St"); The second example 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: Table table2 = new Table(shell, SWT.CHECK SWT.HIDE_SELECTION); table2.setbounds(10,80,270,80); table2.setheadervisible(true); TableColumn fruit = new TableColumn(table2,SWT.LEFT); fruit.settext("fruit"); fruit.setwidth(100); TableColumn colour = new TableColumn(table2,SWT.LEFT); colour.settext("colour"); colour.setwidth(170); TableItem fruit1 = new TableItem(table2,SWT.NONE); fruit1.settext(0,"apple"); fruit1.settext(1,"red"); fruit1.setchecked(true); TableItem fruit2 = new TableItem(table2,SWT.NONE); fruit2.settext(new String[] {"Kiwi","Green"); fruit2.setbackground(new Color(display,255,0,0)); TableItem fruit3 = new TableItem(table2,SWT.NONE); fruit3.settext(new String[] {"Banana","Yellow"); The last example implements the FULL_SELECTION style, which means that when you select a table item, the entire item is highlighted instead of just the first field. The first column is resizable, meaning you can drag it larger or smaller. Note that the three columns each have a different horizontal alignment. This example also shows how you can select an item using code: Table table3 = new Table(shell, SWT.FULL_SELECTION); table3.setlinesvisible(true); table3.setbounds(10,180,270,80); TableColumn first = new TableColumn(table3,SWT.LEFT); first.setresizable(true); first.settext("first"); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 3

71 first.setwidth(80); TableColumn second = new TableColumn(table3,SWT.CENTER); second.settext("second"); second.setwidth(80); TableColumn third = new TableColumn(table3,SWT.RIGHT); third.settext("third"); third.setwidth(80); String[] numbers = new String[] {"One","Two","Three"; TableItem firstitem = new TableItem(table3,SWT.NONE); firstitem.settext(numbers); TableItem seconditem = new TableItem(table3,SWT.NONE); seconditem.settext(numbers); TableItem thirditem = new TableItem(table3,SWT.NONE); thirditem.settext(numbers); TableItem fourthitem = new TableItem(table3,SWT.NONE); fourthitem.settext(numbers); table3.select(1); The following window incorporates all three of these examples: TabFolder To add a tab folder to your shell, use the following code: TabFolder tabfolder1 = new TabFolder(shell,SWT.NONE); The BORDER style can be used for tab folders. If you create a tab folder and do not add any TabItems to it, it resembles a raised composite: Advanced SWT Widgets University of Manitoba Tutorial 3 Page 4

72 To create a TabItem, use the following code: TabItem item1 = new TabItem(tabFolder1,SWT.NONE); There are no styles available for TabItems. There are two important steps for creating tab items. First, if you want a label on the tab, you need to use the settext() method. Secondly, in order to populate the tab item, you need to set the control which it contains, using the setcontrol() method: item1.settext("buttons"); item1.setcontrol(buttoncomp); Now, in this example, buttoncomp is a Composite, as you will see in the following example. Since you can only set one control into a tab item, a Composite is usually desired. In this case, you can add multiple controls to the composite, and they will all appear on the specified tab item. This is all the code that is necessary, as events for tab changing are built into the TabItem and TabFolder controls: TabFolder tabfolder1 = new TabFolder(shell,SWT.NONE); tabfolder1.setbounds(10,10,270,250); //Set up the button tab Composite buttoncomp = new Composite(tabFolder1,SWT.NONE); Button button1 = new Button(buttonComp,SWT.PUSH); button1.setsize(100,100); button1.settext("hello"); button1.setlocation(0,0); Button button2 = new Button(buttonComp,SWT.ARROW); button2.setbounds(150,0,50,50); TabItem item1 = new TabItem(tabFolder1,SWT.NONE); item1.settext("buttons"); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 5

73 item1.setcontrol(buttoncomp); //Set up the label tab Composite labelcomp = new Composite(tabFolder1,SWT.NONE); Label label1 = new Label(labelComp,SWT.NONE); label1.settext("here are some labels for your viewing pleasure"); label1.setbounds(0,0,250,20); Label label2 = new Label(labelComp,SWT.NONE); label2.settext("a label is a fine fingered fiend"); label2.setbounds(0,40,200,20); TabItem item2 = new TabItem(tabFolder1,SWT.NONE); item2.settext("labels"); item2.setcontrol(labelcomp); This example creates a TabFolder with two TabItems, one for buttons and one for labels. When the window initially appears, it looks like this: If you click on the Labels tab, the tab items switch, and the screen looks like this: Advanced SWT Widgets University of Manitoba Tutorial 3 Page 6

74 Slider, Scale and Progress Bar The slider, scale and progress bar are all very similar controls. However, they use a few different methods in order to function properly. We will briefly go over all three, and then show a small example for each control.we will start with the slider and the scale, as these two controls have many of the same functions. To create a slider, use the following code: Slider slider1 = new Slider(shell, SWT.HORIZONTAL); To create a scale, use the following code: Scale scale1 = new Scale(shell, SWT.HORIZONTAL); The styles that can be applied to a slider or a scale are BORDER, HORIZONTAL and VERTICAL. You can set the minimum and maximum value of a slider or a scale using the setminimum and setmaximum methods. slider1.setmaximum(100); slider1.setminimum(0); You may wish to set the selection of the slider or the scale. This indicates where on the slider you will place the thumb, or where on the scale the marker will be positioned. In this case, the left edge of the thumb will be placed halfway between the two ends of the slider. slider1.setselection(50); On a slider, you can also set the size of the thumb. This size is relative to the minimum and maximum values that you have set. For example, if you set the minimum to 0 and the maximum to 100, then setting the thumb size to 30 will make the thumb about one third of the length of the slider. slider1.setthumb(30); On a scale, you can set the page increment. This determines how often measuring bars are placed on the scale. For example, if you set the minimum to 0 and the maximum to 500, then setting the page increment to 50 means there will be 10 measuring bars along the scale. It will place a bar every 50 places, relative to the minimum and the maximum. scale1.setpageincrement(50); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 7

75 The following example puts together these two widgets and the methods discussed: Slider slider1 = new Slider(shell, SWT.HORIZONTAL); slider1.setbounds(0,0,200,20); slider1.setselection(50); slider1.setmaximum(100); slider1.setminimum(0); slider1.setthumb(30); Scale scale1 = new Scale(shell, SWT.HORIZONTAL); scale1.setbounds(0,40,200,40); scale1.setminimum(0); scale1.setmaximum(500); scale1.setselection(100); scale1.setpageincrement(50); This code produces the following window: Next, we are going to look at the progress bar. To create a progress bar, use the following code: ProgressBar progressbar1 = new ProgressBar(shell,SWT.HORIZONTAL); The styles that can be used for progress bar are BORDER, VERTICAL and HORIZONTAL, just like the slider and scale. However, you can also use the style SMOOTH, which turns the progress indicator into a smooth bar. For a progress bar, the only properties which you may want to set are minimum and maximum values, and the selection. The selection indicator is based on the minimum and Advanced SWT Widgets University of Manitoba Tutorial 3 Page 8

76 the maximum. Unlike the scale or the slider, you cannot set the width of the progress indicator bars, or the size of the progress marker. The following code illustrates these methods: ProgressBar progressbar1 = new ProgressBar(shell,SWT.HORIZONTAL); progressbar1.setminimum(0); progressbar1.setmaximum(100); progressbar1.setselection(30); progressbar1.setbounds(10,10,250,20); This produces the following window: Menus and MenuItems: We will look at two examples of menus. The first will be the most basic use, to create a simple menu with a selectable option on it, and capture the event generated when it is selected. The second, larger example will demonstrate some of the more complicated aspects of menus, including submenus, accelerators, mnemonics, additional Events that may be captured, and the various different types of menu items available. To set up menus, you make use of the Menu and MenuItem widgets (see SimpleMenuDemo.java). To create the menu bar that spans the top of your Shell use the following code: Menu menu = new Menu(shell, SWT.BAR); shell.setmenubar(menu); The style constant for the menu bar must be SWT.BAR. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 9

77 Next we want to add an item to the menu bar. MenuItem file = new MenuItem(menu, SWT.CASCADE); file.settext("file"); This will create a File item on the menu bar. If you run it with just these lines, you will see the menu bar at the top of the shell, with the option File displayed. However, if you select one of the options, nothing will happen. Make sure that the style constant is SWT.CASCADE, because otherwise you will be unable to attach a drop-down menu to it. We will now attach a menu to the File option. Menu filemenu = new Menu(shell, SWT.DROP_DOWN); file.setmenu(filemenu); This creates the file menu, and attaches it to the correct MenuItem on the Menu bar. 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. MenuItem actionitem = new MenuItem(filemenu, SWT.PUSH); actionitem.settext("action"); This creates a basic selectable menu item on the File menu. To be notified when this option is selected, we add a listener, like so: actionitem.addlistener(swt.selection, new Listener() { public void handleevent(event e) { System.out.println("Action performed!"); ); This will output the words Action performed! to the console, whenever the Action option is chosen. 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. The resulting menu looks like this: Advanced SWT Widgets University of Manitoba Tutorial 3 Page 10

78 We begin our longer example (see MenuDemo.java) with the same initial code as our first example. The first additional feature we will consider is types of MenuItems other than SWT.PUSH. Alternate choices for the style constants are CHECK, RADIO, SEPARATOR and CASCADE. The first is a checkbox item, while the second is a radio button item. SEPARATOR is used to provide an non-selectable dividing horizontal line between other items. The following code demonstrates the CHECK, SEPARATOR and RADIO options. It will create a separator, then a checkbox-style menu item, followed by radio-button style menu item. MenuItem separator = new MenuItem(filemenu, SWT.SEPARATOR); final MenuItem radioitem = new MenuItem(filemenu, SWT.RADIO); radioitem.settext("radio"); final MenuItem checkitem = new MenuItem(filemenu, SWT.CHECK); checkitem.settext("check"); The next few lines add listeners to the Check and Radio items, which output their current values (true or false) to the console. radioitem.addlistener(swt.selection, new Listener() { public void handleevent(event e) { System.out.println("Radio item toggled to:"+ radioitem.getselection()); ); checkitem.addlistener(swt.selection, new Listener() { public void handleevent(event e) { System.out.println("Check item toggled to:" + checkitem.getselection()); ); We will 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. We create a new MenuItem with style Advanced SWT Widgets University of Manitoba Tutorial 3 Page 11

79 constant SWT.CASCADE, and then create a new menu to attach to it. We then call setmenu on the MenuItem to which we are attaching the new menu. MenuItem cascadeitem = new MenuItem(filemenu, SWT.CASCADE); cascadeitem.settext("cascade"); Menu submenu = new Menu(shell, SWT.DROP_DOWN); cascadeitem.setmenu(submenu); The next few lines add a menu item to our new submenu. The new item that we add will be called SubAction. Notice that in the settext method call, there is an ampersand(&) before the letter S. This will create a mnemonic for the SubAction command, so that when the submenu is displayed, pressing the S-key will select it as if you had used the mouse. The call in the following line, to setaccelerator associates the SubAction menu item with the key combination Control-S, so the user can execute the SubAction command without bringing up the menu. final MenuItem subactionitem = new MenuItem(submenu, SWT.PUSH); subactionitem.settext("&subaction\tctrl+s"); subactionitem.setaccelerator(swt.ctrl+'s'); We add an additional option to the sub-menu which will be used to demonstrate enabling and disabling of MenuItems. This checkbox will enable/disable the SubAction we just added. final MenuItem enableitem = new MenuItem(submenu, SWT.CHECK); enableitem.settext("enable SubAction"); There are a variety of additional listeners that we didn t look at in our simple example. One of these is the ability to add listeners to Menus (rather than MenuItems as we did before.) Here we add a MenuListener to our submenu, which notifies us whenever it is shown or hidden. submenu.addmenulistener(new MenuListener() { public void menushown(menuevent e) { System.out.println("SubMenu shown"); public void menuhidden(menuevent e) { System.out.println("SubMenu hidden"); ); Next we will demonstrate the ability to enable and disable menu items, using another checkbox item. The first line disables SubAction to begin with, so its text is shown shaded in the menu. When disabled you cannot select the option, and its accelerator also Advanced SWT Widgets University of Manitoba Tutorial 3 Page 12

80 no longer works. The code after that sets up the listener, which will disable or enable the SubAction MenuItem depending on whether the Enable SubAction checkbox is checked. subactionitem.setenabled(false); enableitem.addlistener(swt.selection, new Listener() { public void handleevent(event e) { System.out.println("Toggling \"Enable SubAction\" to " + enableitem.getselection()); subactionitem.setenabled(enableitem.getselection()); ); Before when we set up a listener for the Action item, we used a generic Listener. Here for demonstration purposes we make use of the more specific SelectionListener. AS before we merely print a message to the console on activation. subactionitem.addselectionlistener(new SelectionListener() { public void widgetselected(selectionevent e) { System.out.println("SubAction performed!"); public void widgetdefaultselected(selectionevent e) { ); Another interesting listener is the ArmListener, which is fired when a menuitem is highlighted with the mouse or keyboard, but not yet selected. The following code prints a message when the SubAction is armed. subactionitem.addarmlistener(new ArmListener() { public void widgetarmed(armevent e) { System.out.println("SubAction armed!"); ); A final listener type is the HelpListener. By pressing F1/Help key, the HelpListener is activated, which maybe useful for providing help on various options. subactionitem.addhelplistener(new HelpListener() { public void helprequested(helpevent e) { System.out.println("Help requested on SubAction"); ); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 13

81 The result is the following menu. Selecting the Enable SubAction option will enable SubAction. Hitting Ctrl+S will execute SubAction as well, but only if Enable SubAction is checked. All the listeners print messages to the console when they are activated. There are numerous other facilities available for Menus and MenuItems, but we ve attempted to cover the majority of the useful ones. Next we will look briefly at a simple pop-up menu. Popup Menus Pop-up menus (see PopupMenuDemo.java) are useful for context-sensitive menus on different areas of the screen, rather than making the user go to a Menu bar at the top of the screen and hunt for the option they want. By right-clicking on a Composite that has a pop-up menu associated, the menu will appear floating beside your mouse, allowing you to select from a list of options like a regular menu. In the demo below, we will create a button, in a composite, on a shell. Then we will create 2 pop-up menus, and associate one with the shell and composite, the other with the button. We create the menu, as we did with other menus, except the style constant must be SWT.POP_UP. We then add an item to it, and attach a listener to capture selection events. This will be the menu for the shell and composite. Menu popupmenu = new Menu(shell, SWT.POP_UP); MenuItem actionitem = new MenuItem(popupmenu, SWT.PUSH); actionitem.settext("other Action"); actionitem.addlistener(swt.selection, new Listener() { public void handleevent(event e) { System.out.println("Other Action performed!"); ); Next we repeat the process, with this menu being associated with the button. Menu popupmenu2 = new Menu(shell, SWT.POP_UP); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 14

82 MenuItem buttonitem = new MenuItem(popupmenu2, SWT.PUSH); buttonitem.settext("button Action"); buttonitem.addlistener(swt.selection, new Listener() { public void handleevent(event e) { System.out.println("Button Action performed!"); ); Next we create the composite and button, and place them on the shell. Composite c1 = new Composite (shell, SWT.BORDER); c1.setsize (100, 100); c1.setlocation(25,25); Button b = new Button(c1, SWT.PUSH); b.settext("button"); b.setsize(50,50); b.setlocation(25,25); Finally, we set the pop-up menus for each part. Notice that we reuse the pop-up menu from the Composite on the Shell. b.setmenu(popupmenu2); c1.setmenu (popupmenu); shell.setmenu (popupmenu); 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 shot we can see the pop-up menu that is displayed when right-clicking on the button. Although this is a simple example, pop-up menus can be just as complex as the earlier Menu bar example, with submenus, radio-items, listeners, etc. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 15

83 Trees Trees are used to display information in a hierarchical format, such as displaying folders and sub-folders in a file manager, or classes and subclasses in a class browser tool. The following code (TreeDemo.java) creates the tree. The standard style constants for Trees are SWT.MULTI, SWT.SINGLE, and SWT.CHECK. SINGLE allows the selection of only one item from the Tree at a time, while MULTI allows multiple selections. Only one of SINGLE and MULTI may be specified at a time. CHECK adds check boxes beside each item in the tree. As an example, Eclipse uses this CHECK style of tree for choosing which files to import/export from a folder. The Tree we create here allows multiple selections, and has a border. As usual, the first parameter to the Tree constructor is the Composite on which we want to place the tree, and the second is the SWT style constants. final Tree tree = new Tree(shell, SWT.MULTI SWT.BORDER); tree.setsize(150, 150); tree.setlocation(5,5); We must now attach TreeItems to the tree. Here we create three top (root) level items on the Tree. The first parameter to the constructor is the Tree that we want to attach the items to. The second is the SWT style constant, and the (optional) last parameter is the index at which to place the item in the tree. In this example, the argument 1 specifies that My Documents will appear as the middle element in the top-level of the tree, even though it was added after the other two items. TreeItem mycomp = new TreeItem(tree, SWT.NONE); mycomp.settext("my Computer"); TreeItem netplaces = new TreeItem(tree, SWT.NONE); netplaces.settext("my Network Places"); TreeItem mydocs = new TreeItem(tree, SWT.NONE, 1); mydocs.settext("my Documents"); To create children TreeItems off of these root-level nodes, we use a similar constructor, except that instead of specifying the Tree to attach them to, we specify the TreeItem that they will appear under. 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. TreeItem harddisk = new TreeItem(myComp, SWT.NONE); harddisk.settext("local Disk (C:)"); TreeItem floppy = new TreeItem(myComp, SWT.NONE, 0); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 16

84 floppy.settext("3.5 Floppy (A:)"); We can continue the process of creating sub-trees indefinitely, simply by creating more TreeItems off of other TreeItems. Here we extend the tree to a third level by creating a TreeItem off of the Local Disk TreeItem. TreeItem progfiles = new TreeItem(hardDisk, SWT.NONE); progfiles.settext("program Files"); We can also add an image to a TreeItem. We load the image as usual (see the section on Images), and then use TreeItem s setimage method, as follows: Image icon = new Image(display, "arrow.bmp"); progfiles.setimage(icon); When the progfiles item is visible in the tree, the image will be displayed to the left of the text of the item. We will now add a listener to the tree. In our examples with menus, the listeners were added to the MenuItems, but in the case of Trees, listeners are associated with the tree as a whole. We add a selection listener to the Tree, and can then use the getselection() method of the tree to return a list of the selected TreeItems. In the example below, we listen for changes in the selection(s), get an array of TreeItems that are selected and print out the text from each item. tree.addselectionlistener(new SelectionAdapter() { public void widgetselected(selectionevent e) { TreeItem[] t = tree.getselection(); System.out.print("Selection: "); for(int i = 0; i < t.length; i++) { System.out.print(t[i].getText() + ", "); System.out.println(); ); 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. tree.addtreelistener(new TreeListener() { public void treecollapsed(treeevent e) { System.out.println("Tree collapsed."); public void treeexpanded(treeevent e) { System.out.println("Tree expanded."); ); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 17

85 The resulting program should look something like this: If you use a tree with the SWT.CHECK style, TreeItem s getchecked() method can be used to test whether a particular item in the tree has been checked. ToolBars We will now consider tool bars. These are often useful for providing handy visual shortcuts to frequently used tasks, rather than requiring users to dig through complicated menus. The buttons on a toolbar behave in a very similar manner to standard buttons, except that they are grouped on a toolbar, and they can contain images and text at once. We will create a simple toolbar (ToolBarDemo.java) with several of the standard types of buttons, with and without images and text. First we create and position the toolbar on the shell. final ToolBar bar = new ToolBar(shell,SWT.HORIZONTAL); bar.setsize(380,150); bar.setlocation(10,10); We want to place an image on some of the buttons, so we must first load it into an Image object. Image icon = new Image(display, "arrow.bmp"); Next, we instantiate three ToolItems. Each is of the basic push button style. The first will contain the text Push, the second will contain the image we just loaded, and the third will hold both the image and the text. ToolItem pushitem1 = new ToolItem(bar, SWT.PUSH); pushitem1.settext("push"); ToolItem pushitem2 = new ToolItem(bar, SWT.PUSH); pushitem2.setimage(icon); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 18

86 ToolItem pushitem3 = new ToolItem(bar, SWT.PUSH); pushitem3.settext("push"); pushitem3.setimage(icon); As with menus, we have a SEPARATOR style to create a visible separation between items on the toolbar. This is done using a variation of the following line. ToolItem sep = new ToolItem(bar, SWT.SEPARATOR); Again, as with regular buttons and menus, we have CHECK and RADIO style buttons. ToolItem s getselection() method can be used to test if a particular radio or check button is selected at any given time. ToolItem checkitem = new ToolItem(bar, SWT.CHECK); checkitem.settext("check"); ToolItem sep2 = new ToolItem(bar, SWT.SEPARATOR); We now add 2 radio buttons, a separator, and another 2 radio buttons. There are two important things to notice here. The first is that the radio behaviour is done automatically, (as opposed to the case of Menus where this behaviour must be programmed by hand by the application programmer.) The second point is that the behaviour only occurs for radio buttons that are adjacent to one another. If another type of ToolItem is between two RADIO ToolItems, the two will not behave as a group, but instead will be independently selectable. The following piece of code demonstrates this by creating two groups separated by a SEPARATOR ToolItem. ToolItem radioitem1 = new ToolItem(bar, SWT.RADIO); radioitem1.settext("radio 1"); ToolItem radioitem2 = new ToolItem(bar, SWT.RADIO); radioitem2.settext("radio 2"); ToolItem sep3 = new ToolItem(bar, SWT.SEPARATOR); ToolItem radioitem3 = new ToolItem(bar, SWT.RADIO); radioitem3.settext("radio 3"); ToolItem radioitem4 = new ToolItem(bar, SWT.RADIO); radioitem4.settext("radio 4"); The last kind of ToolItem that we can create is a drop-down button. The left half of the button acts as a standard push button, while the right half has a downward arrow indicating a drop-down menu. In order to actually attach a drop-down menu to a dropdown ToolItem, you must capture the selection event on that Item, and use the SelectionEvent s (x,y) coordinates to determine where to place the corresponding pop-up menu on the screen. There is a snippet of code demonstrating this technique on the SWT Advanced SWT Widgets University of Manitoba Tutorial 3 Page 19

87 Resources page on the Eclipse.org web site. We ve taken this code and modified it to fit within this example. final ToolItem dropdown = new ToolItem(bar, SWT.DROP_DOWN); dropdown.settext("drop-down"); final Menu menu = new Menu(shell, SWT.POP_UP); MenuItem choice = new MenuItem(menu, SWT.PUSH); choice.settext("choices"); dropdown.addlistener(swt.selection, new Listener() { public void handleevent(event event) { if (event.detail == SWT.ARROW) { Rectangle rect = dropdown.getbounds(); Point pt = new Point(rect.x, rect.y + rect.height); pt = bar.todisplay(pt); menu.setlocation(pt.x, pt.y); menu.setvisible(true); ); Finally, we demonstrate some basic event handling for ToolBars, by adding a SelectionListener to one of our push buttons. A message is printed to the console when the correct (leftmost) button is pressed. pushitem1.addselectionlistener( new SelectionListener () { public void widgetselected(selectionevent e) { System.out.println("Push button one selected."); public void widgetdefaultselected(selectionevent e) { ); The resulting screen will look like this: CoolBars CoolBars are used to create toolbar-like elements that can be dynamically repositioned by the user. For example, the toolbars at the top of the screen in the Eclipse workbench are Advanced SWT Widgets University of Manitoba Tutorial 3 Page 20

88 CoolBars, since you can click on the vertical bars (that look like this: ) and drag them around to reposition the groups of buttons on the toolbar. Similar CoolBars also appear in Microsoft Word and Internet Explorer. We will create a simple CoolBar (CoolBarDemo.java), consisting of three CoolItems. Each CoolItem represents a piece of the CoolBar that can be moved around. We can place whatever Controls we like on each CoolItem. In the following example, we will create one empty CoolItem, two CoolItems containing Buttons and a final CoolItem containing a ToolBar. We create the CoolBar in a standard way, and give it a border. Then four CoolItems are created, specifying bar as the CoolBar to which they should be added. final CoolBar bar = new CoolBar(shell, SWT.BORDER); CoolItem item1 = new CoolItem(bar, SWT.NONE); CoolItem item2 = new CoolItem(bar, SWT.NONE); CoolItem item3 = new CoolItem(bar, SWT.NONE); CoolItem item4 = new CoolItem(bar, SWT.NONE, 2); Next we must go through the process of creating each of the Controls that we will subsequently place on the CoolItems. The first is a flat button with a border, that will be used to demonstrate locking and unlocking of the CoolBar. Button button1 = new Button(bar, SWT.FLAT SWT.BORDER); button1.settext("button"); button1.pack(); By packing 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 and unlock the CoolBar each time it is clicked on. Locking the toolbar removes the ability to click and drag the CoolItems around within the bar. button1.addselectionlistener(new SelectionAdapter() { public void widgetselected(selectionevent e) { bar.setlocked(!bar.getlocked()) ; ); The next button is just a regular button, to be placed in its own CoolItem. Button button2 = new Button(bar, SWT.PUSH); button2.settext("another button"); button2.pack(); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 21

89 A common use of CoolBars is to create toolbars that can be dynamically rearranged by the user. This is how Eclipse uses them. The next piece of code places a basic 2-button toolbar on its own CoolItem. ToolBar tools = new ToolBar(bar, SWT.NONE); ToolItem b1 = new ToolItem(tools, SWT.FLAT); b1.settext("tool"); ToolItem b2 = new ToolItem(tools, SWT.FLAT); b2.settext("bar"); tools.pack(); After we have created each of the controls, we can use CoolItem s setcontrol() method to associate the controls with the right CoolItems. We also use setsize to set the initial size of the each control. Notice how the setminimumsize method is called on item3. This ensures that when the user rearranges the CoolBar, the CoolItem contain the ToolBar doesn t shrink beneath the size we request, which in this case is the size of the ToolBar itself. Point size = button1.getsize(); item1.setcontrol(button1); item1.setsize(item1.computesize(size.x, size.y)); size = button2.getsize(); item2.setcontrol(button2); item2.setsize(item2.computesize(size.x, size.y)); size = tools.getsize(); item3.setcontrol(tools); item3.setsize(item3.computesize(size.x, size.y)); item3.setminimumsize(size); Lastly, setwrapindices is used to wrap some CoolItems onto the next row at a particular index. setsize is called on bar to specify its size on the shell. bar.setwrapindices(new int[] {3); bar.setsize(300, 120); Here is what the CoolBar looks like initially: Advanced SWT Widgets University of Manitoba Tutorial 3 Page 22

90 After some rearrangement, and locking of the CoolBar, the screen looks like this: Graphics SWT provides a wide variety of graphics capabilities. These capabilities are centred largely in the GC class, which we will look at first. Graphics Contexts The graphics context, or GC, is the class that you will use to do most of your drawing and displaying of images using SWT. It provides a large number of basic graphics functions, which may be useful if you are doing custom graphics or widgets. It allows you to: draw or fill rectangles, ovals, lines, polygons, or text set the background and foreground colours set clipping regions copy regions to images or other areas of the same widget display images get and set text/font characteristics. In this demo (GCDemo.java), we will create a Canvas, and use it to draw on. Note that you can obtain a GC for nearly any widget, and draw on it just as we will with Canvas. After we create the canvas, we will make use of several of the methods of GC to demonstrate the range of graphics functions available in SWT. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 23

91 To create the canvas, we use the standard constructor, and set the size and location of the widget. Canvas canvas = new Canvas(shell, SWT.BORDER); canvas.setsize(150, 150); canvas.setlocation(20, 20); Next we open the shell. This is an important step, because if the shell is not open when we do the drawing onto the canvas, the resulting shapes and text will not appear. shell.open(); To get a GC for a particular widget, we use the following code: GC gc = new GC(canvas); This graphics context applies just to canvas, and any drawing we do on it will be clipped to the canvas. That is, if we draw outside the boundaries of the canvas, it will not be displayed on neighbouring areas of the shell. A basic task in graphics is to draw and fill rectangles. We do this with drawrectangle and fillrectangle. drawrectangle uses the current foreground colour (black, so far) to draw the rectangle. The parameters are the (x, y) coordinates of the rectangle, followed by the width, and height of the rectangle. In this example, the upper left corner is at (3, 5) and the lower left is at (3+20, 5+25) = (23, 30). gc.drawrectangle(3, 5, 20, 25); fillrectangle is similar to drawrectangle, except that the filling is done with the current background colour (currently the default, gray). Since we haven t set the background colour here, the filled rectangle will not be visible on the screen. gc.fillrectangle(30, 5, 20, 25); The easiest way to get colours to work with is to use Display s getsystemcolor method in conjunction with an SWT colour constant. It is possible to specify custom colours, and this technique will be covered later on. Color blue = display.getsystemcolor(swt.color_blue); Color red = display.getsystemcolor(swt.color_red); Now that we have some colours, we can set the foreground colour. The lines after that demonstrate some other basic drawing functions. Note that corresponding fill functions exist for Oval and Polygon. In the Oval case, the parameters specified represent a Advanced SWT Widgets University of Manitoba Tutorial 3 Page 24

92 rectangle that bounds the oval. For Polygon, the integer array specifies x and y coordinates of points, alternating x and y. gc.setforeground(blue); gc.drawline(80, 20, 100, 80); gc.drawoval(40, 40, 10, 10); gc.drawpolygon(new int[] {100, 100, 120, 120, 140, 100); We will now demonstrate what filling looks like, by setting the background colour and drawing some additional filled rectangles. Notice that a filled rectangle doesn t cover the exact same space as a drawn rectangle. The fill covers from the top left point to one row and one column less than the corresponding drawn rectangle. In this code, we create a filled rectangle, and another filled rectangle with a drawn rectangle at the same coordinates. gc.setbackground(red); gc.fillrectangle(20, 100, 20, 20); gc.fillrectangle(50, 100, 20, 20); gc.drawrectangle(50, 100, 20, 20); Another useful feature is drawing text. The drawstring() method is used for this purpose, specifying the string and the x,y coordinates. gc.drawstring("text", 120, 20); We can also set clipping regions, so that drawing is restricted to a particular clipping window within the widget we are drawing on. The setclipping method works similar to the drawrectangle method, taking (x, y, width, height) integer parameters. In the code below we will clip a filled oval to a particular region. The clipping has no effect on previously drawn shapes. gc.setclipping(40, 60, 40, 40); gc.filloval(30, 50, 30, 25); Clipping windows can also be specified using Regions, which are essentially the union of a set of rectangles. This can allow for more complex clipping areas. Clipping is the last of the major drawing functions covered in this example. There is one more important step however. Numerous graphics classes in the SWT libraries use resources that are allocated at the OS level, and as such they must be explicitly freed up by the programmer. The standard code we have been using did this for display, after the shell was closed. In our example, GC must be disposed with the line: Advanced SWT Widgets University of Manitoba Tutorial 3 Page 25

93 gc.dispose(); This line can be placed after the last line where drawing is done. It is usually a good policy to dispose of graphics objects like this as soon as you are finished using them. Other classes that usually require explicit disposal include: Colors, Images, and Fonts. You may have noticed that we did not dispose of the Colors blue and red in our example. The reason for this is that they are pre-allocated system colours. A general rule of thumb for disposing of objects is that if you created it, you should dispose of it. Similarly, if you didn t create it, it is not your responsibility to dispose of it. Later on we will demonstrate how to create custom Colors in SWT and these must be explicitly disposed of. Getting back to our example, the output of the program will look something like the following: GC contains numerous other functions for graphics, including setting line width and style, getting characteristics of text, and copying areas of the widget. These are detailed in the SWT javadocs. In the previous example, there was a major flaw in the program. If you minimize the window, or drag it so that part of the canvas is obscured, the drawing that was done is erased. This is because we did the drawing only once when the program started up, and the drawing we did is never repainted a second time. Eg. After dragging the window off the edge of the screen, part of what we have drawn is erased, and never repainted. In order to detect when the canvas needs to be repainted, we must add a PaintListener to it. This next Advanced SWT Widgets University of Manitoba Tutorial 3 Page 26

94 demo (GCDemo2.java) retains the rectangle in the top-right, and repaints it whenever it becomes obscured. Note: It is rare that it should ever be necessary to do any drawing outside of a PaintListener, and it should be avoided most of the time. Canvas canvas = new Canvas(shell, SWT.BORDER); canvas.setsize(150, 150); canvas.setlocation(20, 20); canvas.addpaintlistener(new PaintListener() { public void paintcontrol(paintevent e) { GC gc =e.gc; gc.drawrectangle(3, 5, 20, 25); ); shell.open(); The paintlistener will detect whenever canvas is repainted, and execute the paintcontrol method which draws our rectangle. Note that shell.open() occurs after the PaintListener is added, because the initial painting is done when the shell is opened. If we only add the PaintListener after opening the shell, the rectangle will not be drawn until the next time the canvas must be repainted, ie after the canvas is obscured, or minimized, and then becomes visible again. Also, notice how we obtained our GC. The PaintEvent contains the gc for the object that must be repainted, so we simply access it. There is no need to dispose of this GC because we did not allocate it. The result of the above code will look like the following screenshot. Minimizing, moving, and resizing and similar operations have no apparent effect on the rectangle we have drawn, because it gets repainted when necessary. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 27

95 Fonts and Colors Fonts and Colors are another two important components of graphics in SWT. Both are resources allocated in the OS, so they must be explicitly disposed of, just like GC and Display. As in the previous example, we will use a PaintListener to do our drawing. This time, however, we will draw directly on the shell, just to demonstrate that you don t necessarily have to be using a Canvas widget as your drawing surface. shell.addpaintlistener(new PaintListener() { public void paintcontrol(paintevent e) { GC gc = e.gc; Display d = e.widget.getdisplay(); We use a Color constructor to create a new colour, specifying the Display and the red, green,and blue values for the colour. Each of these values should be in the range Since we created the colour, we must dispose of it, so you will see a dispose call at the end of the method. Color color = new Color(d, 120, 42, 105); gc.setforeground(color); Similarly, we create a new font using a Font constructor, and passing the font name, point size, and font style. The font styles are specified as bitwise ORs of SWT.BOLD, SWT.NORMAL, and SWT.ITALIC. Once the font has been created, we call the GC method setfont, and pass it our new font. Text that is drawn after that will use our new font. As for Color, a Font must be disposed of when we are done with it, so we call font.dispose(). Font font = new Font(d, "Arial", 24, SWT.BOLD SWT.ITALIC); gc.setfont(font); We use GC s drawstring() method to paint some text to the screen with our new font and color. gc.drawstring("text", 20, 20); Again, we dispose of our graphics objects, except GC because we didn t create it here. color.dispose(); font.dispose(); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 28

96 ); shell.open() Notice that we call shell.open() after we have added the listener, so that when it is initially drawn, our drawing occurs as well. The result looks like this: Images Images are used to allow your program to load, draw on and display images. The types of files we can open include: BMP (Windows Bitmap), ICO (Windows Icon), JPEG, GIF, and PNG. A simple example (ImageDemo.java) of using an image is the following, which will load an image from a file, and draw it onto the shell. First we set up the shell in the standard way: Display display = new Display(); Shell shell = new Shell(display); shell.setsize(140,100); Next we load the image from a file, and open the shell to draw on it. We pass display as the Device parameter to the Image constructor, and a String representing the file name and path as the second argument. Notice that we next open the shell, because the shell must be open before we draw to it. (Also, note that we loaded the image before opening the shell. If we swap the ordering of the following 2 lines, we may see a slight delay between when the shell is displayed, and then the image is drawn to it, because loading the image from a file takes some time.) Image img = new Image(display, "EclipseBannerPic.jpg"); shell.open(); Now we acquire a graphics context (or GC) for the shell, so that we can draw on it, and then call drawimage() to draw the image onto our shell. The first parameter to this version of the drawimage function is the image itself, and the remaining 2 parameters are the x and y coordinates that it is to be drawn to on the shell. GC gc = new GC(shell); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 29

97 gc.drawimage(img, 0, 0); After the event loop, there is one more important command. img.dispose(); This disposes of the image and frees its resources. This is very crucial, because images are heavyweight objects that require OS resources. Certain operating systems may limit the number of Images available at once, so it is important to release them when you no longer intend to use them. Here is the resulting screen. Notice that if you minimize or reduce the size of the window, the area of the image obscured by the screen is wiped away, and doesn t come back. This is because we drew the image only once, and didn t provide code to redraw it if the window was altered. JAR Files If you intend to package your program and images into a JAR file, there are some modifications you must make to your code to ensure that the images will still load successfully. This is because the images are now inside a JAR file, and the Image constructor can no longer access them directly via the file system. The code you must use to locate and create an image looks like the following: InputStream is = getclass().getresourceasstream("eclipsebannerpic.jpg"); Image img = new Image(display, is); In the ImageDemo.java code, you can substitute this code for the single line that creates the image, and it should work correctly. If the image is packaged in the JAR file in a location other than at the root level (ie. It s in a subdirectory within the JAR) you will need to specify this path in the getresourceasstream call as well. Eg. If the image is in an images subdirectory within the JAR, you would need to specify getresourceasstream( images/eclipsebannerpic.jpg ) The first line gets an InputStream from the image file in the JAR. It is just a stream of bytes representing the contents of the file. getclass() returns an object of type Class for the current class. The Class class contains the method getresourceasstream which is used to load resources, and returns an InputStream. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 30

98 The InputStream returned is then used to construct an Image object using an alternate constructor. This same technique for loading the images can work within Eclipse as well, as long as the image file is located in the same folder as the.class files (or some subfolder of that folder). For the demos that follow however, we will just use the basic technique used earlier. There are a variety of other useful constructors for Images. Image(Device device, int width, int height) is used to create a blank image with a specified width and height. Image(Device device, Rectangle bounds) has the same purpose, except that the width and height are specified using a Rectangle object. A common use of these blank Images is to perform drawing to an Image offscreen, and then use GC.drawImage() to quickly draw the whole image to the screen. This can prevent flicker since doing drawing directly to the screen can be slow. In OffscreenImageDemo.java, we create a blank Image, and a GC for it. We then use the GC to draw a line onto the image while it is in memory. Then we create a second GC for the shell, and use this GC to draw the image to the screen. Image img = new Image(display, 50,50); shell.open(); GC imggc = new GC(img); imggc.drawline(10, 20, 30, 40); GC shellgc = new GC(shell); shellgc.drawimage(img, 0, 0); In this case there likely wouldn t be much difference if we had simply used shellgc to draw the line directly to the screen, since drawing a single line would be very quick. However, if we were drawing a complicated figure repeatedly to perform some kind of animation, doing the drawing offscreen could noticeably reduce flicker. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 31

99 In this example (ImageButtonDemo.java), we demonstrate how to show an image on a button. It is a simple matter of loading/drawing the image, and then call setimage on the button in question, with the image as an argument. We will also use this example to demonstrate another constructor, used for making duplicates of a given Image. Image(Device device, Image srcimage, int flag) is used to create a duplicate of srcimage, possibly with some modification specified by flag. flag may be one of SWT.IMAGE_COPY, SWT.IMAGE_GRAY, and SWT.IMAGE_DISABLE. We load the original image, as usual. Image original = new Image(display, "EclipseBannerPic.jpg"); Now we create 3 duplicates of it, one for each possible flag value. Image copy = new Image(display, original, SWT.IMAGE_COPY); Image gray = new Image(display, original, SWT.IMAGE_GRAY); Image disable = new Image(display, original, SWT.IMAGE_DISABLE); We initialize three buttons(b1, b2, and b3) in the standard way and set their size and locations. (This code is omitted since it is repetitive of something we ve already learned.) The next important chunk is actually setting the image on the button. This is done as follows: b1.setimage(copy); b2.setimage(gray); b3.setimage(disable); The top button (b1) shows an exact copy of the original image. The middle button (b2) displays a gray-scale version of the image. The lowest button (b3) displays a disabled version of the image (gray-scale, and somewhat faded.) Advanced SWT Widgets University of Manitoba Tutorial 3 Page 32

100 Note that if you call settext on one of these buttons, the text will replace the Image. The standard Button widget cannot display text and an image simultaneously. Also, notice that it isn t really effective to duplicate an Image with SWT.IMAGE_COPY, unless you intend to make changes to the resulting image and don t wish to destroy the original Image in memory. Otherwise we could simply use the original Image in multiple places without penalty. Minimizing the number of images loaded is to our advantage in that it reduces the memory and OS resource requirements of the program. In the example above, the exact duplicate was only created to demonstrate the functionality of the constructor. We can also add images to items on menus. The code that follows (ImageMenuDemo.java) will load arrow.bmp and display it beside the text of the action MenuItem. We first create a standard menu with a single choice. Menu bar = new Menu(shell, SWT.BAR); shell.setmenubar(bar); MenuItem file = new MenuItem(bar, SWT.CASCADE); file.settext("file"); Menu filemenu = new Menu(shell, SWT.DROP_DOWN); MenuItem action = new MenuItem(fileMenu, SWT.PUSH); file.setmenu(filemenu); action.settext("action"); Next we load an image, and call MenuItem s setimage method. Image icon = new Image(display, "arrow.bmp"); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 33

101 action.setimage(icon); This is the result. Setting images (as we ve just done for Buttons and MenuItems) can also be performed on a variety of other widgets, such as TreeItems, TableItems, ToolItems and more. Splash Screens This example (SplashDemo.java) demonstrates how to produce a simple splash screen effect for your program. The basic technique is to create a Shell with the SWT.NO_TRIM style specified. This produces a shell with no window border around it, which we can place an image in to create the splash screen. We will then just put the running thread to sleep for a few seconds, and then dispose of everything. In a real program you would dispose of the resources and then continue with the real program. This program differs slightly from the standard ones, so the entire code of the rundemo() method will be listed here. First we create a display as usual, followed by a shell. The only difference in the shell creation code is that we pass the NO_TRIM style as a parameter to the constructor. Display display = new Display(); Shell shell = new Shell(display, SWT.NO_TRIM); Next we load the Image that we want to display, and get an ImageData object that contains information about the Image. This is used to size the shell to match the size of the image. Image image = new Image(display, "splash.jpg"); ImageData imdata = image.getimagedata(); shell.setsize(imdata.width, imdata.height); The next few lines center the new shell on your display. First getbounds() is called, which specifies the size of the screen. We then take the width and height values, and subtract the width and height of our images from each. Then dividing by 2 gives us the correct coordinate-value for the shell to be placed at. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 34

102 Rectangle r = display.getbounds(); int shellx = (r.width - imdata.width) / 2; int shelly = (r.height - imdata.height) / 2; shell.setlocation(shellx, shelly); Next we open the shell, and create a graphics context for it. Since we set the shell to be the same size as our image, we can draw the image at coordinates (0, 0) in the shell, and the image will fill the shell completely. As usual drawimage is used to write the image to the shell. shell.open(); GC gc = new GC(shell); gc.drawimage(image, 0, 0); Once we have displayed the image on the screen, we simply want to pause a moment for the user to look at the splash screen. We create this pause by putting the current thread to sleep for a few seconds. The static method Thread.sleep(int) will do this for us. The parameter is the number of milliseconds that the thread s execution should be suspended for. final int SLEEP_TIME = 4000; try { Thread.sleep(SLEEP_TIME); catch (InterruptedException e) { And lastly, we dispose of the resources we used in the standard fashion. image.dispose(); shell.dispose(); display.dispose(); When you run the program, the result should look similar to this, with the image floating by itself in the center of the screen. Note that this program simply stops doing anything while the splash screen is displayed. A better use is to display the splash screen while performing any necessary, timeconsuming loading tasks. There is a snippet of code available on the Eclipse.org website that demonstrates this technique. It also displays a progress bar that indicates how close the program is to completion of the loading process. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 35

103 Advanced Widgets Project A project that contains the examples used in this document is available in a zip file format. As was described at the end of the previous document, in order to make it possible to run each demo from a main shell, the instructions used to create each demo had to be modified because Eclipse does not permit an application to create more than one display. When the project is run, the following shell is displayed. Each example can be run by clicking on the associated button. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 36

104 MessageBox A MessageBox is useful to inform or warn the user or to get a basic response from the user. A MessageBox can display a message to the user and provide buttons to allow the user to respond to the system. To add a message box that asks the user if they like apples and gives them possible replies of "Yes", "No" or "Cancel", use the following code: MessageBox messagebox = new MessageBox(shell, SWT.ICON_QUESTION SWT.YES SWT.NO SWT.CANCEL); messagebox.setmessage("do you like apples?"); Possible styles for the type of message box are ICON_ERROR, ICON_INFORMATION, ICON_QUESTION, ICON_WARNING and ICON_WORKING. Possible styles for the types of responses are OK, OK CANCEL, YES NO, YES NO CANCEL, RETRY CANCEL and ABORT RETRY IGNORE. A message box style and a response style can be logically ORed, with the ' ' operator, to produce a combination of message boxes. The title of the message box can be set by using the settext() method: messagebox.settext("messageboxdemo"); To make the dialog visible, use the open() method: response = messagebox.open(); The above code will produce the following window: The open() method of the MessageBox class will return an integer representing the response from the user. The response can be processed as in the following code: switch(response){ case SWT.YES: System.out.println("Yes, the user likes apples."); break; case SWT.NO: System.out.println("No, the user does not like apples."); break; case SWT.CANCEL: System.out.println("The user cancelled."); break; Advanced SWT Widgets University of Manitoba Tutorial 3 Page 37

105 ColorDialog A ColorDialog allows users to select a color from a predefined set of available colors. To add a color dialog to your shell, use the following code: ColorDialog colordialog1 = new ColorDialog(shell); colordialog1.settext("colordialog Demo"); colordialog1.setrgb(new RGB(255,0,0)); The above code creates a new instance of the ColorDialog class and adds a title to the dialog by using the settext() method. The setrgb() method can be used to specify the color to be selected when the dialog opens. To make the dialog visible and bring it to the front of the display use the open() method. RGB selectedcolor = colordialog1.open(); This will produce the following window: The open() method 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. The color selected can printed as in the following code: System.out.println("Color Selected:" + selectedcolor); DirectoryDialog A DirectoryDialog allows a user to navigate the file system and select a directory. To add a DirectoryDialog to your shell use the following code: DirectoryDialog directorydialog = new DirectoryDialog(shell); directorydialog.settext("directorydialog Demo"); directorydialog.setfilterpath("c:/program Files"); The above code creates a new instance of the DirectoryDialog class and adds a title to the dialog by using the settext() method. The setfilterpath() method can be used to specify Advanced SWT Widgets University of Manitoba Tutorial 3 Page 38

106 the directory to be selected when the dialog opens. To make the dialog visible and bring it to the front of the display use the open() method. String selecteddirectory = directorydialog.open(); The above code produces the following window: The open() method will return a string describing the absolute path of the selected directory, or null if the dialog was cancelled or an error occurred. The path of the selected directory can be printed as in the following code: System.out.println("Directory Selected:" + selecteddirectory); FileDialog A FileDialog allows a user to navigate the file system and select or enter a file name. To add a FileDialog to your shell use the following code: String[] filterextensions = {"*.txt","*.doc", "*.*"; FileDialog filedialog = new FileDialog(shell, SWT.OPEN); filedialog.settext("filedialog Demo"); filedialog.setfilterpath("c:/"); filedialog.setfilterextensions(filterextensions); String selectedfile = filedialog.open(); This creates a new instance of the FileDialog class, as we did in the previous dialog examples, however this time the style of the dialog will be SWT.OPEN. Other possible styles are SWT.SAVE and SWT.MULTI. As in the DirectoryDialog example, the title of the dialog can be set with the settext() method. The contents of the directory specified in the setfilterpath() method will be shown when the dialog is opened. The types of files to be shown can be specified by using the setfilterextensions() method. Calling the open() method will produce the following window: Advanced SWT Widgets University of Manitoba Tutorial 3 Page 39

107 The open() method 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 absolute path of the selected file can be printed, as in the following code: System.out.println("File Selected:" + selectedfile); FontDialog A FontDialog allows a user to select a font from all available fonts in the system. To add a FontDialog to your shell use the following code: FontData defaultfontdata = new FontData("Courier",12,SWT.ITALIC); FontDialog fontdialog = new FontDialog(shell, SWT.NONE); fontdialog.settext("fontdialog Demo"); fontdialog.setrgb(new RGB(0,0,255)); fontdialog.setfontdata(defaultfontdata); FontData fontdata = fontdialog.open(); The code creates a new instance of the FontDialog class and sets the title of the dialog as in previous dialog examples. The color of the font can be specified by using the setrgb() method. The font can also be specified by using the setfontdata() method, in the above case, the font face, font size and style will be "Courier", "12" and "Italic" respectively. Calling the open() method will produce the following window: Advanced SWT Widgets University of Manitoba Tutorial 3 Page 40

108 The open() method will return a FontData object describing the font that was selected, or null if the dialog was cancelled or an error occurred. The selected font can be processed as in the following code: if (fontdata!= null){ System.out.println("Font Name Selected:"+fontData.getName()); System.out.println("Font Height Selected:"+fontData.getHeight()); System.out.println("Font Style Selected:"+fontData.getStyle()); System.out.println("Font Colour Selected:"+fontDialog.getRGB()); PrintDialog A PrintDialog allows the user to select a printer and various print-related parameters prior to starting a print job. The add a print dialog to your shell use the following code: PrintDialog printdialog = new PrintDialog(shell, SWT.NONE); printdialog.settext("printdialogdemo"); printdialog.setscope(printerdata.page_range); printdialog.setstartpage(2); printdialog.setendpage(5); printdialog.setprinttofile(true); PrinterData printerdata = printdialog.open(); The creates a new instance of the PrintDialog class and sets the title as in previous dialog examples. The scope of the print job will initially be set to print a range of pages, starting with second page and ending at the fifth page. The 'print to file' option will also be checked. Calling the open() method will produce the following window: Advanced SWT Widgets University of Manitoba Tutorial 3 Page 41

109 The open() method 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. The print information can be processed as in the following code: if (printerdata!= null){ switch(printerdata.scope){ case PrinterData.ALL_PAGES: System.out.println("Printing all pages."); break; case PrinterData.SELECTION: System.out.println("Printing selected page."); break; case PrinterData.PAGE_RANGE: System.out.print("Printing page range. "); System.out.print("From:"+printerData.startPage); System.out.println(" to:"+printerdata.endpage); break; if (printerdata.printtofile) System.out.println("Printing to file."); else System.out.println("Not printing to file."); if (printerdata.collate) System.out.println("Collating."); else System.out.println("Not collating."); System.out.println("Number of copies:"+printerdata.copycount); System.out.println("Printer Name:"+printerData.name); Note that the PrintDialog class contains the 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. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 42

110 Input Dialog A dialog to accept a text response from the user is not available from SWT, however it is possible to create a class that behaves much like the dialogs that we have seen. Firstly, we must create a class that will represent the data that is returned from our dialog. We would like to know if the user submitted their response or did they cancel the dialog. If they did not cancel the dialog, we would like to know the user's text response. The following code represents our data class, complete with a constructor, Getter and Setter methods: public class MyInputDialogData { String textresponse; boolean buttonresponse; MyInputDialogData(){ settextresponse(""); setbuttonresponse(false); public boolean isbuttonresponse() { return buttonresponse; public String gettextresponse() { return textresponse; public void setbuttonresponse(boolean b) { buttonresponse = b; public void settextresponse(string string) { textresponse = string; Next, we must create a class that subclasses the Dialog class. Since this class will be our dialog, we will give this dialog a label to display a message to the user, an area for the user to enter a response, a button for the user to submit the response and another button for the user to cancel the dialog. We will also need a field for the data that will be returned from the dialog. public class MyInputDialog extends Dialog { private Label lblquestion; private Text txtresponse; private Button btnokay; private Button btncancel; private MyInputDialogData data; We now need a method to display our dialog. This method will be analogous to the open() method of the built in dialogs. In order to have the same behaviour as the built in dialogs we have seen, this method will return an instance of our data class. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 43

111 public MyInputDialogData open () { data = new MyInputDialogData(); final Shell shell = new Shell(getParent(), SWT.DIALOG_TRIM SWT.APPLICATION_MODAL); shell.settext(gettext()); shell.setsize(300,150); lblquestion = new Label(shell, SWT.NONE); lblquestion.setlocation(25,10); lblquestion.setsize(150,20); lblquestion.settext("what is your name?"); txtresponse = new Text(shell, SWT.BORDER); txtresponse.setlocation(25,30); txtresponse.setsize(200,20); btnokay = new Button (shell, SWT.PUSH); btnokay.settext ("Ok"); btnokay.setlocation(40,60); btnokay.setsize(55,25); btncancel = new Button (shell, SWT.PUSH); btncancel.settext ("Cancel"); btncancel.setlocation(100,60); btncancel.setsize(55,25); Listener listener = new Listener () { public void handleevent (Event event) { data.setbuttonresponse(event.widget == btnokay); data.settextresponse(txtresponse.gettext()); shell.close (); ; btnokay.addlistener(swt.selection, listener); btncancel.addlistener(swt.selection, listener); shell.open(); Display display = getparent().getdisplay(); while (!shell.isdisposed()) { if (!display.readanddispatch()) display.sleep(); return data; The preceding code sizes and positions each of the dialog's widgets. A listener is then created to handle when the user clicks on a button. The listener will set the appropriate fields of the MyInputDialogData object. The Dialog will then display itself by calling the open() method of the Shell class. Using our input dialog will be much like using the built in dialogs. MyInputDialog midt = new MyInputDialog(shell); midt.settext("my Input Dialog Demo"); MyInputDialogData mydata = midt.open(); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 44

112 The code creates an instance of the MyInputDialog class, sets the text of the window and invokes the open() method. The complete sample code will produce the following window: The data returned by the open() can be processed as in the following code: if (mydata.isbuttonresponse()) System.out.println("The user clicked the 'okay' button."); else System.out.println("The user did not click the 'okay' button."); System.out.println("Response: " + mydata.gettextresponse()); DragAndDrop In this section, we describe how to implement Drag and Drop and Clipboard to transfer text within an SWT application. Drag and Drop provides the user with a quick and easy mechanism to transfer data within an application and between applications. Firstly, we must import all the drag and drop classes: import org.eclipse.swt.dnd.*; To implement Drag and Drop, we must specify which widgets will be our source and destination targets. In the following code, we will specify a label to be our source target. First, create, set and size a label: lblsource = new Label(shell, SWT.BORDER); lblsource.setsize(200,50); lblsource.setlocation(50,50); lblsource.settext("this is the source label"); Next, specify the type of transfer we want. Possible types are TextTransfer, RTFTransfer or FileTransfer. We are only going to show how to transfer unformatted text: Transfer[] types = new Transfer[] {TextTransfer.getInstance(); Then we must specify the type of operations we want to enable on the drag source. Possible operations are DROP_MOVE, DROP_COPY and DROP_LINK. We will only concern ourselves with moving and copying text: Advanced SWT Widgets University of Manitoba Tutorial 3 Page 45

113 int operations = DND.DROP_MOVE DND.DROP_COPY; Create a new instance of the DragSource class, specifying which control will be the source and the operations we want to enable on it and set its transfer type: DragSource source = new DragSource (lblsource, operations); source.settransfer(types); Now we must specify a label to be the target control. First create, set and size a label, then create a new instance of the DragTarget class, indicating which control will be the target, and specifying the operations and transfer types we want enabled. lbltarget = new Label(shell, SWT.BORDER); lbltarget.setsize(200,50); lbltarget.setlocation(50,150); lbltarget.settext("this is the destination label"); DropTarget target = new DropTarget(lblTarget, operations); target.settransfer(types); In order to be notified of when the user starts dragging text we must add a DragSourceAdapter() listener to the source. This is illustrated in the following code: source.adddraglistener (new DragSourceAdapter() { public void dragstart(dragsourceevent event) { if (lblsource.gettext().length() == 0) { event.doit = false; ; public void dragsetdata (DragSourceEvent event) { if (TextTransfer.getInstance().isSupportedType(event.dataType)){ event.data = lblsource.gettext(); public void dragfinished(dragsourceevent event) { if (event.detail == DND.DROP_MOVE) lblsource.settext(""); ); The dragstart() method of the DragSourceAdapter will be executed when the user has begun the actions required to drag the widget. This event gives the application the chance to decide if a drag should be started. The dragsetdata() method will be executed when the user drops data on a drop target, and must provide the data to be dropped. This method must also support all the data transfer types that were specified in the settransfer() method of the drag source. The dragfinished() method will be executed after a drop has been completed successfully or was aborted. This event gives the application the chance to take any appropriate clean up action, for example in a successful move operation the application must remove the data that was transferred. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 46

114 In order to be notified of when the user drops the text over our target, we must add a DropTargetAdapter() to the target. This is illustrated in the following code: target.adddroplistener (new DropTargetAdapter() { public void drop(droptargetevent event) { if (event.data == null) { event.detail = DND.DROP_NONE; return; lbltarget.settext ((String) event.data); ); The drop() method will be executed when the data is being dropped. The drop target can decide how to handle the dropped data in this method. The result of the above code will be the following screenshot: Clicking on the source label and dragging the mouse over the destination label will move the source text to the destination label. To make a copy the text, hold down the Control key when dropping the text. Clipboard The Clipboard provides a mechanism for transferring data from one application to another or within an application. We must first import the drag and drop classes: import org.eclipse.swt.dnd.*; To get access to the operating system's clipboard, we must create a Clipboard object: cb = new Clipboard(myDisplay); Advanced SWT Widgets University of Manitoba Tutorial 3 Page 47

115 Note: As the clipboard object uses system resources, we must make sure to dispose of the clipboard object when we are done with it. This can be done with the dispose() method at the end of our application. Next, we need to create two Text widgets to be our source and destination targets. We will also need two Button widgets so we can copy and paste text to and from the clipboard: txtsource = new Text(shell, SWT.BORDER); txtsource.setsize(200,20); txtsource.setlocation(50,20); btncopy = new Button(shell, SWT.PUSH); btncopy.setsize(100,20); btncopy.setlocation(275,20); btncopy.settext("copy"); txtdestination = new Text(shell, SWT.BORDER); txtdestination.setsize(200,20); txtdestination.setlocation(50,80); btnpaste = new Button(shell, SWT.PUSH); btnpaste.setsize(100,20); btnpaste.setlocation(275,80); btnpaste.settext("paste"); Now we need to add functionality to our buttons so that they can capture events. We need to add selection listeners to our copy and paste buttons. For the copy button, when it is pressed, we want to transfer the data that is in the source Text to the clipboard. However, if there is no data in the source Text, we will do nothing. This is demonstrated in the following code: btncopy.addselectionlistener(new SelectionAdapter(){ public void widgetselected(selectionevent e) { String textdata = txtsource.gettext(); if (textdata == null) return; TextTransfer texttransfer = TextTransfer.getInstance(); Transfer[] types = new Transfer[] {texttransfer; cb.setcontents(new Object[] {textdata, types); ); To transfer data to the clipboard, we must first set up the type of transfers will want to handle. The possible transfer types are TextTransfer and RTFTransfer, however we will only deal with transferring text. To do this, we need to create an array of Transfer containing an instance of the TextTransfer class. Finally, to transfer our data to the clipboard, we use the setcontent() method of the Clipboard class. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 48

116 Next, when the paste button is pressed, we want to transfer the data from the clipboard to the destination Text. If there is no data on the clipboard, we will do nothing. This is demonstrated in the following code: btnpaste.addselectionlistener(new SelectionAdapter(){ public void widgetselected(selectionevent e){ TextTransfer texttransfer = TextTransfer.getInstance(); String data = (String)cb.getContents(textTransfer); if (data == null) return; txtdestination.insert(data); ); We want to concern ourselves only with the TextTransfer type, so we only need to get an instance of the TextTransfer class. We ask for the contents of the clipboard of type TextTransfer by using the getcontents() method. Then, if there is data of type TextTransfer, we insert it into the destination Text. The sample code will produce the following window: Data can be copied from the source Text and pasted in the destination Text or in another application, like Notepad. Data can also be copied from another application and pasted into the destination Text of the Demo. Advanced SWT Widgets University of Manitoba Tutorial 3 Page 49

117 Eclipse Layouts 1, 2 by Shantha Ramachandran, University of Manitoba, Winnipeg, Manitoba, Canada Last revised: June 4, 2003 Overview: In this section, we will be discussing the four different types of layout managers you can use for designing a GUI. These four types are FillLayout, RowLayout, GridLayout and FormLayout. A detailed specification on how to use the different layout managers can be found on the eclipse website, in the article entitled Understanding Layouts in SWT. This article can be found at the following address: Layouts/Understanding Layouts.htm. Before reading further or running any examples, it is advised that you read this article, as it is very informative and covers the basic function of all four layout managers. Layout Example: Eclipse offers a plugin to preview how a shell would look using different layouts, called the Layout Example. To run this example, go to the Window menu in Eclipse, and select Show View, then select Other. 1 This work was funded by an IBM Eclipse Innovation Grant. 2 Shantha Ramachandran and David Scuse Eclipse Layouts University of Manitoba Tutorial 4 Page 1

118 From the screen that appears, expand the SWT Examples folder, and choose SWT Layouts. Click OK. The Layout Example will appear, and you can play around with it as you wish. Clicking on the Code button will generate sample code for the layouts that you have defined. Eclipse Layouts University of Manitoba Tutorial 4 Page 2

119 This next section will only cover how to use the layout managers very briefly. As stated above, for more information, you should see the article, Understanding Layouts in SWT. However, this section may be useful to help understand where and when to use the different layout managers, and how they can be useful to you. FillLayout: FillLayout is the most basic of all the layout managers. As you add widgets to the screen, FillLayout arranges them all horizontally in a row or vertically in a column. It spaces them all evenly so the entire composite is filled by the widgets. There is no layout data for FillLayout, so all you need to do is define whether the layout is horizontal or vertical and place the widgets on the screen. This layout manager is useful when you have a list of labels or buttons that you want to arrange on the screen evenly. The good thing about FillLayout is that when you resize the screen, the spacing stays even. The same effect can be achieved with GridLayout, but with a lot more work. The following example shows how you can arrange labels on a screen using FillLayout. Note that you do not have to set any properties for the labels, as the layout manager takes care of their placement: shell.setlayout(new FillLayout(SWT.VERTICAL)); Label label0 = new Label(shell, SWT.NONE); label0.settext("instructions:"); Label label1 = new Label(shell, SWT.NONE); label1.settext("1. Fill in your name"); Label label2 = new Label(shell, SWT.NONE); label2.settext("2. Fill in your age"); Label label3 = new Label(shell, SWT.NONE); label3.settext("3. Fill in your gender"); Label label4 = new Label(shell, SWT.NONE); label4.settext("4. Check the box for employment"); Label label5 = new Label(shell, SWT.NONE); label5.settext("5. Click on OK"); This is the window that results: Eclipse Layouts University of Manitoba Tutorial 4 Page 3

120 Now if we resize the window, the labels are still spaced evenly: Next, we will look at RowLayout, and show how it differs from FillLayout. We will look at this same example again, plus look at a new one as well. RowLayout: RowLayout arranges widgets in rows, as indicated by its name. We can declare a RowLayout to be horizontal or vertical, making the widgets arranged in either horizontal rows or vertical columns. Unlike FillLayout, RowLayout also has some other fields that can be set, such as wrap and pack as well as margins and spacing. If we set the pack field to true, then all widgets will remain their natural size, and they will be placed as far to the left (or the top) as possible. This is a key feature that differentiates RowLayout from FillLayout. For example, if we set the layout for the previous example to a RowLayout with its pack field set to true, initially the window looks the same. However, when we resize it, the widgets remain the same size and are aligned as far to the top as possible: Eclipse Layouts University of Manitoba Tutorial 4 Page 4

121 Another feature of RowLayout that differentiates it from FillLayout is the wrap field. When the wrap field is set to true, if a row is too long for the window, the layout will wrap it around to form two rows. Take for example our previous FillLayout example. If we resize the window and make it too small for all the widgets to fit, they are simply overlapped: However, if we use the same code but a RowLayout instead, the layout manager will compensate for the lack of space and create two columns instead of one: The following example shows how you can use the pack field to evenly space out your widgets. In this example, pack is set to false, so all the buttons on the screen will be the same size. The wrap field is set to true, so depending on the size of the window, there can be more than one row: RowLayout rowlayout = new RowLayout(); rowlayout.pack = false; shell.setlayout(rowlayout); Button b1 = new Button(shell, SWT.PUSH); Eclipse Layouts University of Manitoba Tutorial 4 Page 5

122 b1.settext("address"); Button b2 = new Button(shell, SWT.PUSH); b2.settext("phone Numbers"); Button b3 = new Button(shell, SWT.PUSH); b3.settext("credit Cards"); Button b4 = new Button(shell, SWT.PUSH); b4.settext("organizations"); Button b5 = new Button(shell, SWT.PUSH); b5.settext("cancel"); Button b6 = new Button(shell, SWT.PUSH); b6.settext("ok"); Here are some ideas of what the screen will look like, depending on the size of the window: Eclipse Layouts University of Manitoba Tutorial 4 Page 6

123 Notice how the layout manager attempts to put the buttons in horizontal rows. In the last screen shot, the window is only big enough for one button, so the layout manager has created six rows. GridLayout: GridLayout offers much more flexibility that RowLayout or FillLayout does, but this flexibility comes at a cost. GridLayout has many fields that need manipulating, as well as GridData, which is almost always necessary to add to widgets in order to fully get the benefits of the GridLayout manager. The most important fields to get a handle on with respect to GridLayout are the numcolumn field and the makecolumnsequalwidth field. This allows you to determine the number of columns of widgets you would like on your window, and whether they should all be the same size, or take the size of the widgets. You should always make the number of columns equal to the maximum number that you would desire in a particular row. Once you determine the number of columns, you can make any widget span as many columns as you wish. This allows the placement of the widgets to be very flexible. As opposed to RowLayout, where RowData objects are available but not usually necessary, GridData objects are quite important in a GridLayout. The most important aspect of the GridData objects are the fields which allow you to control the behavior of widgets when the screen is resized. For example, let s look at the following piece of code, which demonstrates lining up labels and text boxes, a very common arrangement: GridLayout gridlayout = new GridLayout(); gridlayout.numcolumns = 2; shell.setlayout(gridlayout); Label label1 = new Label(shell, SWT.NONE); label1.settext("name:"); Text text1 = new Text(shell, SWT.BORDER); Label label2 = new Label(shell, SWT.NONE); label2.settext("age:"); Text text2 = new Text(shell, SWT.BORDER); Label label3 = new Label(shell, SWT.NONE); label3.settext("gender:"); Text text3 = new Text(shell, SWT.BORDER); Button button = new Button(shell, SWT.CHECK); button.settext("have you been employed in the past six months?"); GridData data = new GridData(); data.widthhint = 60; label1.setlayoutdata(data); Eclipse Layouts University of Manitoba Tutorial 4 Page 7

124 data = new GridData(); data.widthhint = 60; label2.setlayoutdata(data); data = new GridData(); data.widthhint = 60; label3.setlayoutdata(data); GridData data2 = new GridData(GridData.FILL_HORIZONTAL); text1.setlayoutdata(data2); data2 = new GridData(GridData.FILL_HORIZONTAL); text2.setlayoutdata(data2); data2 = new GridData(GridData.FILL_HORIZONTAL); text3.setlayoutdata(data2); GridData data3 = new GridData(); data3.horizontalspan = 2; button.setlayoutdata(data3); Note that a separate GridData object has to be declared for each widget. We have two columns in this layout, and the button at the bottom of the screen spans both columns. The window that results from this code is as follows: In this example, the text widgets are set to fill horizontally. This means that not only do the text widgets initialize their size to fill up the rest of the screen width, but also when we resize the screen, they will grab the extra space: Eclipse Layouts University of Manitoba Tutorial 4 Page 8

125 Notice the difference if we take out the lines of code that give us this feature. Not only do the text widgets become the default size, but they will not resize when the screen is resized: Once again, take a look at the Eclipse article Understanding Layouts in SWT for a more complex example of GridLayout. The many different fields regarding space usage for GridLayout are difficult to understand. However, once you get a handle on them, they can give you extreme flexibility for resizing each widget differently on a screen resize. FormLayout: The last layout we will look at is FormLayout. FormLayout is the newest layout manager, and it is debatable whether it is any better than GridLayout. Whatever the case, FormLayout offers an enormous amount of flexibility, like GridLayout, but in an extremely different fashion. When using a GridLayout, it is necessary to plan ahead, as the order in which you add your widgets is the order in which they appear in the grid. When using a FormLayout, each widget is separate from all other widgets in terms of the overall layout. In RowLayout, the RowData object is useful, but not altogether necessary. In GridLayout, the GridData object is fairly necessary but the layout manager can function Eclipse Layouts University of Manitoba Tutorial 4 Page 9

126 without it. In FormLayout, the FormData object is absolutely crucial. If you do not assign a FormData object to each widget, they will all be placed in the same default space, and all your widgets will simply sit on top of one another. Each widget has its own FormData object, which is placed by using FormAttachments. The idea behind the FormAttachments, and essentially behind the FormLayout, is that we can tack the edges of the widgets to various places on the window. We can assign positions for the top, bottom, left and right edges of each widget. We can define these positions as being percentages, offsets from other widgets, or even alignments. To fully get a handle on how FormAttachments work, we will go over a fairly complex example. Example Putting it all Together: The following example takes all the previous examples of the different types of layouts and puts them together using a FormLayout. Each of the previous examples are placed in a composite, and the three composites are placed on the shell using FormLayout. We will go over the example piece by piece. First we will set the layout onto the shell, and create a composite which holds the FillLayout example, called fillcomp. We want this composite to sit in the top left corner with it taking up 75% of the height of the screen, and 40% of the width. We need to create a FormData object for fillcomp with the following FormAttachment objects: shell.setlayout(new FormLayout()); //Fill Layout panel Composite fillcomp = new Composite(shell, SWT.BORDER); fillcomp.setlayout(new FillLayout(SWT.VERTICAL)); Label label0 = new Label(fillComp, SWT.NONE); label0.settext("instructions:"); Label label1 = new Label(fillComp, SWT.NONE); label1.settext("1. Fill in your name"); Label label2 = new Label(fillComp, SWT.NONE); label2.settext("2. Fill in your age"); Label label3 = new Label(fillComp, SWT.NONE); label3.settext("3. Fill in your gender"); Label label4 = new Label(fillComp, SWT.NONE); label4.settext("4. Check the box for employment"); Label label5 = new Label(fillComp, SWT.NONE); label5.settext("5. Click on OK"); FormData formfill = new FormData(); formfill.top = new FormAttachment(0, 10); formfill.left = new FormAttachment(0, 10); formfill.bottom = new FormAttachment(75, 0); formfill.right = new FormAttachment(40,0); fillcomp.setlayoutdata(formfill); Eclipse Layouts University of Manitoba Tutorial 4 Page 10

127 Notice how we are putting a 10 pixel offset from the top and the left of the screen. We could eliminate this by setting the margin fields of FormLayout. Next we will create the composite for the RowLayout code, called rowcomp. We want this composite to be placed below fillcomp, and we would like it to stretch to the left, right and bottom, and fill out whatever space is left: //Row Layout panel Composite rowcomp = new Composite(shell, SWT.NONE); RowLayout rowlayout = new RowLayout(); rowlayout.pack = false; rowcomp.setlayout(rowlayout); Button b1 = new Button(rowComp, SWT.PUSH); b1.settext("address"); Button b2 = new Button(rowComp, SWT.PUSH); b2.settext("phone Numbers"); Button b3 = new Button(rowComp, SWT.PUSH); b3.settext("credit Cards"); Button b4 = new Button(rowComp, SWT.PUSH); b4.settext("organizations"); Button b5 = new Button(rowComp, SWT.PUSH); b5.settext("cancel"); Button b6 = new Button(rowComp, SWT.PUSH); b6.settext("ok"); FormData formrow = new FormData(); formrow.top = new FormAttachment(fillComp, 10); formrow.left = new FormAttachment(0, 10); formrow.bottom = new FormAttachment(100, -10); formrow.right = new FormAttachment(100, -10); rowcomp.setlayoutdata(formrow); Finally, we will create the composite for the GridLayout portion, called gridcomp. We want gridcomp to be aligned with fillcomp on the bottom, and to be attached to it on the left. We will extend to the edges on the top and the right: //Grid Layout panel Composite gridcomp = new Composite(shell, SWT.NONE); GridLayout gridlayout = new GridLayout(); gridlayout.numcolumns = 2; gridcomp.setlayout(gridlayout); Label label11 = new Label(gridComp, SWT.NONE); label11.settext("name:"); Text text1 = new Text(gridComp, SWT.BORDER); Label label12 = new Label(gridComp, SWT.NONE); label12.settext("age:"); Eclipse Layouts University of Manitoba Tutorial 4 Page 11

128 Text text2 = new Text(gridComp, SWT.BORDER); Label label13 = new Label(gridComp, SWT.NONE); label13.settext("gender:"); Text text3 = new Text(gridComp, SWT.BORDER); Button button = new Button(gridComp, SWT.CHECK); button.settext("have you been employed in the past six months?"); GridData data = new GridData(); data.widthhint = 60; label11.setlayoutdata(data); data = new GridData(); data.widthhint = 60; label12.setlayoutdata(data); data = new GridData(); data.widthhint = 60; label13.setlayoutdata(data); GridData data2 = new GridData(GridData.FILL_HORIZONTAL); text1.setlayoutdata(data2); data2 = new GridData(GridData.FILL_HORIZONTAL); text2.setlayoutdata(data2); data2 = new GridData(GridData.FILL_HORIZONTAL); text3.setlayoutdata(data2); GridData data3 = new GridData(); data3.horizontalspan = 2; button.setlayoutdata(data3); FormData formgrid = new FormData(); formgrid.top = new FormAttachment(0,10); formgrid.left = new FormAttachment(fillComp,10); formgrid.right = new FormAttachment(100,-10); formgrid.bottom = new FormAttachment(fillComp,10, SWT.BOTTOM); gridcomp.setlayoutdata(formgrid); Note that in this example, all four sides of each FormData have been defined, this is not always necessary. If one or more edges are not defined, the widget will take its default size and determine the placement of its other edges. The window that results: Eclipse Layouts University of Manitoba Tutorial 4 Page 12

129 The important thing to note with this screen is the effect it has upon resize. Notice that since we have layouts within layouts, the resize effects are applied twice. Let s see what happens when we make the screen larger: Eclipse Layouts University of Manitoba Tutorial 4 Page 13

130 Since the rowcomp composite was attached to the left and the right of the screen, when the window gets larger, the composite fills out the space. The RowLayout within rowcomp now has enough room to place all the buttons in one row. Similarly, the gridcomp was attached to the left side of the window, so the text widgets will grab the extra space provided by the GridLayout. The fillcomp composite was attached at 40% of the screen, and as the screen gets larger, the composite will get larger too, so that it always sits at 40% on its left side. The same kind of effects will take place when the screen is made smaller: Eclipse Layouts University of Manitoba Tutorial 4 Page 14

131 There are many more features to all the layouts described in this chapter. Although it may take some time to become familiar with enough of the layout managers to be able to use them efficiently and effectively, it will soon become clear that it is much easier to design an SWT interface using layouts than without. Eclipse Layouts University of Manitoba Tutorial 4 Page 15

132 Client Billing Application 1, 2 by David Scuse and Christopher Batty, University of Manitoba, Winnipeg, Manitoba, Canada Last revised: October 23, 2003 Overview: In this document, we describe a simple application that keeps track of payments made to client accounts. Setup: The current version of the application is configured to use an HSQLDB database (although connections to a MySQL database and an MS Access database are also included in comments at the beginning of ClientBillingDB.java). //Load the hsqldb driver Class.forName("org.hsqldb.jdbcDriver"); url = "jdbc:hsqldb:clients"; // stored on disk mode //Open the connection conn = DriverManager.getConnection(url, "SA", ""); System.out.println("Opened HSQLDB database."); //Load the MySQL driver //Class.forName("com.mysql.jdbc.Driver"); //url = "jdbc:mysql://localhost/clients"; //Open the connection //conn = DriverManager.getConnection(url, "root", ""); //System.out.println("Opened MYSQL database."); //Load the MS Access drivers //Remember that in Windows 2000 and XP, ODBC connections are defined // in the Control Panel --> Admin Tools --> Data Sources //Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //url = "jdbc:odbc:clients"; //Open the connection //conn = DriverManager.getConnection(url, "", ""); //System.out.println("Opened ACCESS database."); 1 This work was funded by an IBM Eclipse Innovation Grant. 2 David Scuse and Christopher Batty Client Billing Application University of Manitoba Tutorial 5 Page 1

133 To use an HSQLDB, download the HSQLDB system from and copy hsqldb.jar into the JRE lib/ext folder (this jar file is also included in the HSQLDB folder). A sample database (clients.properties and clients.script) has been included in the project folder. To use a MYSQL database, download the MYSQL server from install the server and create the database. A script that creates the database has been included in the MYSQL folder in the project folder. If MYSQL is used, it is worthwhile downloading the MYSQL Control Center which provides GUI access to the databases. To use an MS Access database under Windows, an ODBC connection that links the database, clients.mdb, and the logical database name used in the system, Clients, must be defined. ODBC connections are defined in the control panel (ODBC) on earlier versions of Windows and are defined in DataSources (ODBC) in the Administrative Tools section of the Control Panel in more recent versions of Windows. Running the System Once the database connection has been made, the system can be run. Currently, there is not a lot of functionality, the system is intended merely to illustrate the use of various SWT controls in a working system. A collection of clients has been predefined in each database. The following screenshots show the contents of the Access database. Clients can be selected clicking on the client name in the Current Clients panel on the left of the screen. Client Billing Application University of Manitoba Tutorial 5 Page 2

134 To access clients by the client identifier, click the View by ID button under the Current Clients panel. To locate a specific client (or clients), type any part of the client s name (or ID when the ID view is used) into the filter box and then type enter. Note that after the filter has been applied, the client must still be selected by clicking on the client s name (or ID). Client Billing Application University of Manitoba Tutorial 5 Page 3

135 To return to the entire list of clients, erase the characters in the filter box and refresh the view either by typing enter or by clicking on the View by name or View by ID button. For each client, a list of payments that have been made against the client s account can be viewed on the Transactions tab. To enter a new transaction, click the New button and then fill in the necessary information about the transaction. Client Billing Application University of Manitoba Tutorial 5 Page 4

136 Click Save and the transaction is added to the window. Transactions can be deleted by selecting a transaction and then clicking the Delete button. Similarly, transactions can be edited by selecting a transaction, clicking the Edit button, making the changes, and then clicking the Save button. Layout Managers: The controls used in the development of the GUI for this application were initially given hard-coded locations and sizes (via the setsize() and setlocation() methods). (The source for the GUI is in the class ClientBillingUI.java.) If the size of the window in which the application is run is made smaller by the user, some controls will no longer be visible. Note that when the window is made smaller, scroll bars are not available. Client Billing Application University of Manitoba Tutorial 5 Page 5

137 For many applications, this behaviour is not a problem since the window is unlikely to be resized. However, for some users and applications, resizing windows is a frequent occurrence. The appropriate use of a layout manager can made the resizing of a window more convenient since the components are resized as the window is resized. We rewrote the GUI for the client billing application to use layout managers. Note that only ClientBillingUI.java had to be modified, the other classes remained unchanged. When the application is run, it has the following initial appearance. Now if the window is resized, controls do not simply disappear. Although, some information is truncated if the window is resized significantly. Client Billing Application University of Manitoba Tutorial 5 Page 6

138 The number of lines of code for both the original (without layouts) version and the layouts version are approximately the same. However, the layouts version has significantly less complexity since absolute locations and sizes are not used. Instead, with the form layout, the position is specified as a percentage of the available space. This permits designer to specify more or less where the control is to be placed and permits the layout manager to position controls in a more intelligent manner. Another design point to note is that the windows are subdivided into composites (groups) and controls are added to the appropriate composite/group. This organization provides more flexibility than if controls are added directly onto the underlying shell or tab folder. Printing: Since most billing systems require the ability to print invoices or statements, a Print facility was included on the Clients tab. Clicking the Print button generates a printed copy of the current client s information on the user s default printer. The source statements for this facility can be found in the printtransbutton in ClientBillingUI.java. The printing is performed using a StyledText widget. The following information on Joe Dirt would be printed. Client Report - Joe Dirt Account ID: 100 First Name: Joe Last Name: Dirt Date of birth: Phone Number: dirt@eclipse.org Address: Winnipeg, Manitoba Miscellaneous information: some stuff Transactions A present Payment Another payment Total balance: Client Billing Application University of Manitoba Tutorial 5 Page 7

139 Missing Functionality: This system is not quite complete, there are various extensions that would have to be included before the system could actually be used. A negative value may be entered as a transaction amount but credits and debits would have to be improved to prevent confusion on the part of the user. Having buttons that filter the transactions by year and month would also be helpful in a realistic system. The printing facility could be expanded to permit the user to select either an individual client or all clients and also to permit the user to print all transactions or selected transactions (for example, transactions for the current month or between two userspecified dates). Bugs: When the description field of a transaction is edited, sometimes the change is applied to all transactions with the same transaction ID, even though the client number is not the same.???? Client Billing Application University of Manitoba Tutorial 5 Page 8

140 Compiling Eclipse Applications for Windows With GCJ/MinGW 1, 2 by David Scuse, University of Manitoba, Winnipeg, Manitoba, Canada Last revised: Monday, July 14, 2003 Overview: In this document, we examine the creation of native (Windows) executables for Eclipse applications (not for Eclipse itself). While we have concentrated on Windows aspects, the equivalent systems should work without any difficulty on Linux. We will eventually test the generation of native Linux executables. The advantage of compiled Eclipse application executables is that they do not require the JRE, they are self-contained except for the one swt dll. The applications can be distributed in zip format and can be moved around on a machine without requiring changes to the registry (there is no information saved in the Windows registry). GCC and MinGW: To compile Java applications to run on Windows, download the MinGW build of GCC/GCJ 3.3 for win32 from This build uses a slightly older version of Eclipse (Eclipse 2.0.2) but it worked without any problems on the applications that we tested. This build includes a build of the SWT libraries so that the entire Eclipse application can be compiled. (The Swing libraries have not yet been ported to GCC/GCJ.) Special thanks are due to Mohan Embar and Ranjit Mathew for their work in building this win32 version. We tried the GCC 3.4 build of 29 June 2003 (which includes Eclipse 2.1) but ran into some difficulties that could not be easily identified so in this document, we are using GCC/GCJ 3.3 and Eclipse for now. 1 This work was funded by an IBM Eclipse Innovation Grant. 2 David Scuse Compiling Eclipse With GCJ University of Manitoba Tutorial 6 Page 1

141 Once the compiler system has been installed, you are ready to go. Compiles are typically defined in scripts instead of from the command prompt. In this document, we have used Windows command scripts (.bat files) since they are likely more familiar to Windows users than shell scripts. However, the same scripts could be defined using the Windows Bash port msys, available at By using shell scripts instead of Windows command scripts, the same script could also be run under Linux. A complete Windows command script is included with each example. After an Eclipse application has been compiled, a standard Windows exe file is generated. This file can be executed by double-clicking on it. The only Eclipse file that must be present for the exe to run is the swt dll for the associated Eclipse build in these examples, that is swt-win dll. This dll must be available somewhere on the system path; putting it the System32 folder makes it available to all programs. (See the first tutorial, Installing Eclipse, for more information on the swt dll.) All of the applications that were developed in the earlier tutorials have been included in the associated project folder. Note that the required swt dll has also been included in the folder. This folder can be unzipped to any desired location. Note that it is not necessary to have Eclipse installed on the machine for the applications to run. It is also not necessary to have installed the MinGW build of GCC/GCJ 3.3 to run the exe s but it is necessary to install MinGW if you want to compile any other applications. Compiling Eclipse With GCJ University of Manitoba Tutorial 6 Page 2

142 Basic Widgets Project: In this section, we examine the BasicWidgets application that was described in the Basic Widgets tutorial. The folder contains the files shown below. Note that this folder is a copy of the folder used in the Eclipse workspace; it is probably not a good idea to build the executables in the Eclipse workspace folder itself. We will not describe the parameters to GCJ; for more information, see the GCC website at or a GCC book. The build script shown below initially defines some environment variables. These variables indicate the location of the GCC compiler and the GCC SWT libraries that are required. Each source file is then compiled into the corresponding class files which are stored in the bin folder. These files are then collected into a jar file. The source files are then compiled into object files (*.o) and are stored in the obj folder. The object files are then collected into an object library (*.a). Finally, the application is built by the last gcj command that includes the --main parameter. Compiling Eclipse With GCJ University of Manitoba Tutorial 6 Page 3

143 setlocal set prompt=? PATH C:\gcc-3.3\bin;%PATH% set SWT_BASE_DIR=C:\gcc-3.3\swt\win32 set SWT_GCJ_LIB_DIR=%SWT_BASE_DIR%\lib set SWT_JAVA_LIB_DIR=%SWT_BASE_DIR%\swt-2052 set MAIN=BasicWidgetsDemo mkdir bin mkdir obj mkdir include gcj -C -fclasspath=bin;src;%swt_java_lib_dir%\swt.jar -d bin src\basicwidgetsdemo.java gcj -C -fclasspath=bin;src;%swt_java_lib_dir%\swt.jar -d bin src\buttondemo.java gcj -C -fclasspath=bin;src;%swt_java_lib_dir%\swt.jar -d bin src\combodemo.java gcj -C -fclasspath=bin;src;%swt_java_lib_dir%\swt.jar -d bin src\compositedemo.java gcj -C -fclasspath=bin;src;%swt_java_lib_dir%\swt.jar -d bin src\groupdemo.java gcj -C -fclasspath=bin;src;%swt_java_lib_dir%\swt.jar -d bin src\labeldemo.java gcj -C -fclasspath=bin;src;%swt_java_lib_dir%\swt.jar -d bin src\listdemo.java gcj -C -fclasspath=bin;src;%swt_java_lib_dir%\swt.jar -d bin src\textdemo.java cd bin jar cf %MAIN%.jar move %MAIN%.jar..\include cd.. gcj --classpath=obj;bin;%swt_java_lib_dir%\swt.jar c src\basicwidgetsdemo.java -o obj\basicwidgetsdemo.o gcj --classpath=obj;bin;%swt_java_lib_dir%\swt.jar -c src\buttondemo.java -o obj\buttondemo.o gcj --classpath=obj;bin;%swt_java_lib_dir%\swt.jar -c src\combodemo.java -o obj\combodemo.o gcj --classpath=obj;bin;%swt_java_lib_dir%\swt.jar -c src\compositedemo.java -o obj\compositedemo.o gcj --classpath=obj;bin;%swt_java_lib_dir%\swt.jar -c src\groupdemo.java -o obj\groupdemo.o gcj --classpath=obj;bin;%swt_java_lib_dir%\swt.jar -c src\labeldemo.java -o obj\labeldemo.o gcj --classpath=obj;bin;%swt_java_lib_dir%\swt.jar -c src\listdemo.java -o obj\listdemo.o gcj --classpath=obj;bin;%swt_java_lib_dir%\swt.jar -c src\textdemo.java -o obj\textdemo.o cd obj ar -crs lib%main%.a *.o move lib%main%.a..\include cd.. gcj --main=%main% --classpath=.;%swt_java_lib_dir%\swt.jar -o %MAIN%.exe obj\*.o include\*.a -L%SWT_GCJ_LIB_DIR% -lswt endlocal When the exe is run, the following window is displayed. The window is identical to the window generated within Eclipse. Compiling Eclipse With GCJ University of Manitoba Tutorial 6 Page 4

144 If you examine BasicWidgetsDemo.exe, you will find that it is 5.91 MB in size. This is significantly larger than the equivalent C/C++ exe but the exe includes the run-time tools (such as garbage collection) that are required to support the Java environment. JDBC Driver Compilation: Most of the applications in the associated zip file can be compiled without any difficulties. However, the ClientBilling application uses a database and this causes some difficulties for GCC/GCJ since JDBC drivers compiled with GCJ are not readily available. We chose to try the mysql and hsqldb systems since they are both written in Java and are both open source. I would like to thank Dave Orme of Advanced Systems Concepts, Inc. and Kirk Vogen of IBM for providing suggestions about the choice of JDBC drivers. I would also like to thank Erik Poupaert for modifying the mysql driver so that it could be compiled with GCJ and for providing a shell script to do the compile. The folder for the ClientBilling application is shown below. Compiling Eclipse With GCJ University of Manitoba Tutorial 6 Page 5

145 The include folder contains the following files that were created by compiling mysql and hsqldb with GCJ: com-mysql-jdbc.jar; libcom-mysql-jdbc.a; org-hsqldb.jar; and liborghsqldb.a. (The jar files contain the compiled.class files and the a files contain the compiled.o files.) The jdbc driver to be used is identified in the ClientBillingDB.java file. Prior to compiling the application, the desired database management system is selected by adding or removing comments in the source code. //Load the hsqldb driver Class.forName("org.hsqldb.jdbcDriver"); url = "jdbc:hsqldb:clients"; // stored on disk mode //Open the connection conn = DriverManager.getConnection(url, "SA", ""); System.out.println("Opened HSQLDB database."); //Load the MySQL driver //Class.forName("com.mysql.jdbc.Driver"); //url = "jdbc:mysql://localhost/clients"; //Open the connection //conn = DriverManager.getConnection(url, "root", ""); //System.out.println("Opened MYSQL database."); Because the jdbc driver is loaded at dynamically, it is not automatically included when GCJ performs the compile and link of the routines in the application. There are various methods that can be used to force GCJ to include routines that are not referenced Compiling Eclipse With GCJ University of Manitoba Tutorial 6 Page 6

146 statically but the one that we have chosen is to include an additional source file, ForceInclude.java, that references the jdbc driver and any other classes that are loaded dynamically. The following ForceInclude.java file was used with ClientBilling. Note that the Calendar and LocaleInformation classes must also be loaded. In this example, both the mysql and the hsqldb drivers have been included; normally, only one database is used so only one driver would be required. public class ForceInclude { private static final Class class1 = gnu.java.locale.calendar.class; private static final Class class2 = gnu.java.locale.localeinformation.class; private static final Class class3 = com.mysql.jdbc.driver.class; private static final Class class4 = org.hsqldb.jdbcdriver.class; ForceInclude() { Once the application has been built, it can be executed. If mysql is used, the mysql server must first have been installed ( and the database must be created. A script that creates the database is included in the MYSQL folder in the ClientBilling folder. If hsqldb ( is used, no downloads are required since the jdbc driver has already been compiled with the application. An earlier version of hsqldb (1.7.1) did not close the database correctly after the application terminated. This problem appears to have been corrected with version Alpha M (22 JAN 2003). One difference between the version of hsqldb used with Eclipse is that it was compiled with JDK 1.3; this version did not compile correctly with GCJ but changing the source to use JDK 1.4 fixed the compile problems. (HSQLDB includes a build routine switchtojdk14.bat that modifies the source files so that they are compatible with a specific version of the JDK.) Although we used the jdbc-odbc driver in the original Eclipse application, we do not yet have an odbc driver compiled with GCJ for Windows. Compiling Eclipse With GCJ University of Manitoba Tutorial 6 Page 7

147 GCJ Options gcj --help Usage: gcj [options] file... Options: -pass-exit-codes Exit with highest error code from a phase --help Display this information --target-help Display target specific command line options -dumpspecs Display all of the built in spec strings -dumpversion Display the version of the compiler -dumpmachine Display the compiler's target processor -print-search-dirs Display the directories in the compiler's search path -print-libgcc-file-name Display the name of the compiler's companion library -print-file-name=<lib> Display the full path to library <lib> -print-prog-name=<prog> Display the full path to compiler component <prog> -print-multi-directory Display the root directory for versions of libgcc -print-multi-lib Display the mapping between command line options and multiple library search directories -print-multi-os-directory Display the relative path to OS libraries -Wa,<options> Pass comma-separated <options> on to the assembler -Wp,<options> Pass comma-separated <options> on to the preprocessor -Wl,<options> Pass comma-separated <options> on to the linker -Xlinker <arg> Pass <arg> on to the linker -save-temps Do not delete intermediate files -pipe Use pipes rather than intermediate files -time Time the execution of each subprocess -specs=<file> Override built-in specs with the contents of <file> -std=<standard> Assume that the input sources are for <standard> -B <directory> Add <directory> to the compiler's search paths -b <machine> Run gcc for target <machine>, if installed -V <version> Run gcc version number <version>, if installed -v Display the programs invoked by the compiler -### Like -v but options quoted and commands not executed -E Preprocess only; do not compile, assemble or link -S Compile only; do not assemble or link -c Compile and assemble, but do not link -o <file> Place the output into <file> -x <language> Specify the language of the following input files Permissible languages include: c c++ assembler none 'none' means revert to the default behavior of guessing the language based on the file's extension Note: gcj -v help generates additional options specific to the version being used. Note: adding the mwindows option to the final step that generates the exe will remove the black console window from behind the application. Compiling Eclipse With GCJ University of Manitoba Tutorial 6 Page 8

148 Options starting with -g, -f, -m, -O, -W, or --param are automatically passed on to the various sub-processes invoked by gcj. In order to pass other options on to these processes the -W<letter> options must be used. Acknowledgements: Again, special thanks are due to Mohan Embar and Ranjit Mathew for their work in building this win32 version; to Dave Orme of Advanced Systems Concepts, Inc. and Kirk Vogen of IBM for providing suggestions about the choice of JDBC drivers, and to Erik Poupaert for modifying the mysql driver so that it could be compiled with GCJ and for providing a shell script to do the compile. (See also Erik s Freestyler Toolkit in the References section.) References: Kirk Vogen, Create native, cross-platform GUI applications: How GCJ, Linux, and the SWT come together to solve the Java UI conundrum, Kirk Vogen, Create native, cross-platform GUI applications, revisited: An updated look at GCJ and the SWT, Erik Poupaert, The Freestyler Toolkit, ( A more elaborate and complete system for creating and compiling Java/SWT applications.) Additional information on compiling with GCJ can be found using Google. Compiling Eclipse With GCJ University of Manitoba Tutorial 6 Page 9

149 Eclipse Project CDT (C/C++) Plugin Tutorial 1, 2 By Brian Lee, University of Manitoba, Winnipeg, Manitoba, Canada Last revised: February 20, 2004 Overview: This tutorial describes the installation of the Eclipse Project CDT (C/C++ Development Tools) plugin on the Windows platform (running under Linux is mentioned at the end of this tutorial). It describes the entire installation process in detail and is intended for developers who are familiar with the Eclipse environment and would like to develop C/C++ applications in this environment. As a result, it has been assumed that Eclipse has already been installed and that the developer has a basic understanding of how to use Eclipse. To learn more about the Eclipse Project, please visit: In addition, this tutorial is especially useful for students who are uncomfortable writing C/C++ applications in a UNIX or Linux console environment. By using the Eclipse CDT plugin, students can develop C/C++ applications within the Eclipse IDE which provides an intuitive GUI for development. As well, applications developed this way require minimal effort in porting to a UNIX or Linux environment. Requirements: This tutorial has been written in a Windows XP Professional environment, satisfying the following requirements: Java 2 SDK v1.4.1 Eclipse v2.1 MinGW v CDT v1.1.0 GA 1 This work was funded by an IBM Eclipse Innovation Grant. 2 Brian Lee and David Scuse CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 1

150 For instructions on how to install Eclipse, please refer to the following document: Links to downloading MinGW and the Eclipse CDT plugin will be mentioned later in this document. Installing and Setting Up MinGW: In order to be able to compile C and C++ source code using Eclipse, it is necessary to install a C/C++ compiler for Windows. There are several C/C++ compilers available for Windows but MinGW has been selected for this tutorial due to its easy installation and configuration. MinGW is based on GNU toolsets and provides the header files and libraries needed for C/C++ development. At the time of writing this tutorial, the latest version of MinGW that has been tested to work properly with the Eclipse CDT plugin is version To download MinGW, please visit the following site: Click on the Released: MinGW exe link. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 2

151 Click on the link to download the file to your system. Once the download is complete, locate the file on your system and double-click on the file to begin the installation of MinGW. 1.) Click Yes to continue with the installation of MinGW. Click Next to continue. 2.) Click Yes to accept the License Agreement. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 3

152 Note: Unlike other ports of GCC to Windows, the runtime libraries are not distributed using GNU's General Public License (GPL). You, therefore, do not have to distribute your source code with your programs unless, of course, you use a GPL library in your programs. 3 3.) Click Next to continue. 4.) Install MinGW to the following directory: C:\MinGW\ Note: If you install to another directory, remember the directory you install to as it will be used later in this tutorial to complete the installation of the plugin. 3 Taken from: CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 4

153 5.) Click Install to continue. The following screen shows the progress of the installation. MinGW installs a number of GNU GCC and binutils projects, including GDB which is very useful in debugging your C/C++ applications. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 5

154 6.) Click Finish to exit the setup of MinGW. 7.) In order for your system to recognize the MinGW executables from any directory without having to type the full path of the command, the PATH variable needs to be modified: a. Click on Start Control Panel. b. Double-click on System. c. Click on the Advanced tab and then Environment Variables. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 6

155 d. Select Path under the System Variables section and click on Edit. e. Assuming that MinGW has been installed to C:\MinGW, add the following to the end of the Variable value: ;C:\MinGW\bin Note: The semi-colon is used to separate different directories for the PATH variable and must precede the pathname C:\MinGW\bin. Also, please make sure that there are no spaces between the semi-colon and the path name! f. Click OK, then OK, and OK again to apply the changes. 8.) To verify that the installation of MinGW is successful and that the PATH variable has been changed correctly, perform the following steps: a. Click on Start Run b. Type cmd into the dialog box and press OK. c. Type the following into the command prompt and then press ENTER: gcc v CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 7

156 d. If the output of the above command is similar to the screen shown below, then you have successfully installed MinGW and changed the PATH variable: e. If the output of the above command is similar to the screen shown below, this means that the PATH variable has not been changed successfully. Follow the instructions carefully on the previous pages to change the PATH variable: 9.) After verifying that MinGW has been installed and that the PATH variable has been changed successfully, you are ready to install the Eclipse CDT plugin. Installing the Eclipse CDT Plugin: Now that your system is ready to compile C/C++ applications, download the Eclipse CDT plugin at the following site: CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 8

157 1.) Click on the Download Site link: 2.) Scroll down and click on the GA Windows link: 3.) Save the file to your system. 4.) Once the download is complete, unzip the contents of the file: org.eclipse.cdt-win32_1.1.0.bin.dist.zip to the directory where Eclipse.exe is located. For example: C:\eclipse-SDK-2.1-win32\eclipse CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 9

158 Note: After unzipping the file into the Eclipse directory, the contents of the plugin directory should have the following org.eclipse.cdt.* folders: 5.) To verify that the Eclipse CDT plugin has been installed successfully, run Eclipse.exe from the install directory as you normally would. Then perform the following steps: a. Click on Help About Eclipse Platform. b. Click on the Plug-In Details button. c. If your screen looks similar to the following then the Eclipse CDT plugin has been successfully installed: CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 10

159 d. If your screen is missing the C/C++ Development Tools Plug-In components, then verify that the file org.eclipse.cdtwin32_1.1.0.bin.dist.zip has been unzipped to the eclipse\plugins folder as noted on the previous page. Creating a C++ Project using the Eclipse CDT Plugin: This section describes how to create a C/C++ project in Eclipse using the CDT plugin. It has been assumed at this point, that the system is ready to compile C/C++ applications using tools from MinGW and that the Eclipse CDT plugin has been successfully installed. 1.) Run Eclipse from the install directory as you normally would. Once Eclipse is open, create a new C/C++ project by going to File New Project. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 11

160 2.) For this tutorial, you will be creating a C++ Project. When the dialog box pops up, click on C++ and select Standard Make C++ Project. Click Next to continue. 3.) Enter HelloWorld for the name of the project and either use the default workspace or select an alternate location. In the example below, the project is stored in C:\development\HelloWorld. Click Next to continue. 4.) Click on the Build Settings tab and under the Build Command section: a. Uncheck the Use Default checkbox. b. Enter the following in the Build Command field (note that mingw32-make is one string, with no embedded blanks; also, the complete path the the mingw32-make command may be specified): mingw32-make -f makefile c. Click Finish to continue. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 12

161 5.) When the following dialog box pops up, click Yes to continue. 6.) You should now be in the C/C++ Development Perspective, where you can see the HelloWorld project you just created. Now that your project has been created: a. Click on File New File b. Enter main.cpp as the name of the file. c. Click Finish to continue. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 13

162 7.) Once the file is created, copy and paste the following code into main.cpp: #include <iostream> int main(int argc, char *argv[]) { cout << "Hello World" << endl; return 0; // end main Press Ctrl + S to save the file. Note the following error messages in the C-Build window below; these error messages will eventually disappear: 8.) To create the makefile: a. Click on File New File b. Enter makefile as the name of the file. c. Click Finish to continue. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 14

163 9.) Once the file is created, copy and paste the following into the makefile: main : main.o g++ -o main main.o -L C:/MinGW/lib/gcc-lib/mingw32/3.2.3/ -lstdc++ main.o : main.cpp all : clean : g++ -ggdb -c main.cpp ${MAKE main -del main.o The above makefile is simply a generic makefile that could easily be expanded to include a number of different source files. To learn more about the structure of makefiles and how to write your own, check out the many resources available on the Web. After typing the above into the makefile, press Ctrl + S to save the file. Now, some different error messages are displayed in the Tasks window below: CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 15

164 10.) If you look in the C/C++ Project window, you will notice a red X beside main.cpp. The error messages indicate that cout and endl are both undeclared. But the source code in main.cpp looks fine! This is a very common problem and developers tend to get very frustrated in their attempts to solve this problem. The fix is actually quite simple: a. In main.cpp, add the following line right #include <iostream>: using namespace std; b. Press Ctrl + S and your application should compile successfully as shown in the screen below. Note that main.exe has now been created. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 16

165 11.) We are almost done! Now to run your application: a. Click on Run Run b. In the Configurations window, click on C/C++ Local, and then the New button. c. In the Name field, type HelloWorldCpp. d. In the C/C++ Application field, type main.exe. e. The settings on the other tabs will be sufficient for the purpose of this tutorial. f. Then click on the Apply button. Your screen should look like the following: g. Now click the Run button to run your application. You should get the following output in the console window: h. Congratulations! You have just created your first C++ application in Eclipse using the Eclipse CDT plugin. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 17

166 Creating a C Project: Creating a C project is almost identical to creating a C++ project. First, create a new C project called HelloWorldC. Set the Build Command property to: mingw32-make f makefile (the same as for the C++ project). Create main.c with the following contents: Create the makefile with the following contents: main : main.o g++ -o main main.o -L C:/MinGW/lib/gcc-lib/mingw32/3.2.3/ -lstdc++ main.o : main.c g++ -ggdb -c main.c all : ${MAKE main clean : -del main.o Compile the project causing main.exe to be generated. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 18

167 Create the associated Run command. and then Run the project: Once again, Hello world should appear in the console. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 19

168 Running CDT under Linux: We did one simple test of CDT under Linux using the following configuration: Debian Linux with kernel 2.4 Java 2 SDK v1.4.2 Eclipse v2.1.1 MinGW v3.3.2 CDT v1.1.0 Once CDT was unzipped into the Eclipse directory, the default settings for Standard Make C++ project worked correctly since GCC was already installed. If you can compile a C++ program from a console, the default settings should be sufficient for compiling within Eclipse. Basic Console Input/Output: It is quite common that C/C++ programs require user input via the console. The following example shows how to enter input into the console of a program written using the CDT plugin: 1.) Create a new C++ project called HelloWorld which contains the following files: main.cpp makefile 2.) Copy and paste the following code into main.cpp and save the file: #include <iostream> #include <string> using namespace std; int main(int argc, char *argv[]) { string name; cout << "Please enter your name: " << endl; cin >> name; cout << "Hello " + name << endl; return 0; // end main CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 20

169 3.) Copy and paste the following code into makefile and save the file: main : main.o g++ -o main main.o -L C:/MinGW/lib/gcc-lib/mingw32/3.2.3/ - lstdc++ main.o : main.cpp g++ -ggdb -c main.cpp all : ${MAKE main clean : -del main.o 4.) There should be no errors in the C-Build window and the project should compile itself successfully, generating an executable file called main.exe: If you get a Build Error message in the C-Build window, verify that your build settings are setup correctly. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 21

170 a. Right-click on the HelloWorld project and click properties. b. Select C/C++ Project on the left hand side. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 22

171 c. Uncheck the Use Default checkbox under the Build Command section and type the following into the Build Command box: mingw32-make -f makefile d. Click OK. e. Right-click on the HelloWorld project and click on Rebuild. The project should compile itself successfully as shown in the screen below. Note that main.exe has now been created. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 23

172 5.) To run the application: a. Click on Run Run b. In the Configurations window, click on C/C++ Local, and then the New button. c. In the Name field, type HelloWorld. d. In the C/C++ Application field, type main.exe. e. The settings on the other tabs will be sufficient for the purpose of this example. f. Then click on the Apply button. Your screen should look like the following: g. Now click the Run button to run your application. You should get the following output in the console window: CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 24

173 h. Type your name and then press Enter. The next line should read Hello [name] and then the program terminates. Note: If you are having problems entering text into the console, make sure that your cursor is blinking at the end of all text in the console. To position the cursor at the end, simply press Ctrl + End while the cursor is blinking in the console. After performing this step, you should be able to enter text into the console. Basic File Input/Output and Command Line Arguments: Occasionally, a question on an assignment may require you to create a program that reads in command line arguments, such as the names of input and output files. The following example shows how to provide command line arguments to applications at the beginning of execution: 1.) Create a new C++ project called HelloWorld which contains the following files: main.cpp names.txt makefile (For detailed instructions on how to do this, please refer to Part I of this tutorial under the section Creating a Project using the Eclipse CDT Plugin. 2.) Copy and paste the following code into main.cpp and save the file: #include <iostream> #include <fstream> #include <string> using namespace std; // Constants #define BUFFER_SIZE 50 #define ARRAY_SIZE 20 // Global variables int numelements = 0; void sort(char *elements[]) { bool swap = true; char *temp = NULL; while(swap) { swap = false; for (int i = 0; i < (numelements - 1); i++) { if (strcmp(elements[i], elements[i + 1]) > 0) { CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 25

174 temp = elements[i]; elements[i] = elements[i + 1]; elements[i + 1] = temp; swap = true; int main(int argc, char *argv[]) { char buffer[buffer_size]; char *listofnames[array_size]; string inputfilename; string outputfilename; ifstream inputfile; ofstream outputfile; if(argc!= 3) { cout << "Error: Please enter input and output files "; cout << "as command line arguments!" << endl; else { inputfilename = argv[1]; outputfilename = argv[2]; inputfile.open(inputfilename.c_str()); outputfile.open(outputfilename.c_str()); // Read names from input file and store into array while(!inputfile.eof() && numelements < (ARRAY_SIZE - 1)) { inputfile.getline(buffer, BUFFER_SIZE); char *p = new char[strlen(buffer) + 1]; strcpy(p, buffer); listofnames[numelements] = p; numelements++; // Sort elements in array sort(listofnames); // Print elements in array to output file for(int i = 0; i < numelements; i++) { outputfile << listofnames[i] << endl; inputfile.close(); outputfile.close(); return 0; // end main The previous block of code simply reads in two command line arguments the first argument is the name of the input file and the second argument is the name of the output file. The program will read from the input file, store the names into a vector, CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 26

175 and sort these elements alphabetically. Lastly, it will write the ordered list of names to the output file. 3.) Copy and paste the following names into names.txt and save the file: Brian Michelle Jeff Lori Ainsley Jimmy Bob Lorisa John 4.) Now, to specify command line arguments when running your application: a. Click on Run Run b. In the Configurations window, click on C/C++ Local, and then the New button. c. In the Name field, type HelloWorld. d. In the C/C++ Application field, type main.exe. e. Click the Arguments tab. f. In the C/C++ Program Arguments textbox, enter the following: names.txt output.txt g. The settings on the other tabs will be sufficient for the purpose of this example. h. Then click on the Apply button. Your screen should look like the following: CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 27

176 i. Now click the Run button to run your application. You should see a new file called output.txt in the directory view of your project: j. Double-click on output.txt to open the file and you should see the list of names that was in input.txt, sorted alphabetically in ascending order: CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 28

177 Debugging Code: Debugging is an essential skill that every programmer needs to master, whether to fix a problem in an application or even to step through the application slowly to see how it works. Fortunately debugging C/C++ applications on the Eclipse platform using the CDT plugin is very straightforward. Continuing from the example described in the previous section, let s take a look at how to set breakpoints and debug the application: 1.) Switch to the Debug perspective: a. Click on Window Open Perspective Other b. Select the Debug perspective and click OK. c. Your perspective should resemble something like the following: CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 29

178 2.) In order to have access to the basic C/C++ debugging functionality, perform the following steps: a. Click on Window Customize Perspective b. Expand the Other branch, check the C/C++ Debug box, and click OK. 3.) Let s set our first breakpoint: a. Open main.cpp and scroll down to just before the vector of names is sorted: CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 30

179 b. Right-click in the margin and then click Add Breakpoint. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 31

180 4.) Now that we have a breakpoint at that spot, we can being to debug our application: a. Click on Run Debug b. In the Configurations window, click on HelloWorld (this configuration should already exist after completing the example from the previous section). c. Click the Debug button. Just minimize the Windows console window that pops up and your screen should look something like the following: CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 32

181 5.) Let s further analyze the previous screen before proceeding with the debugging of our application: a. The Variables window displays all the local variables currently within the scope of the current block of code. Also note the tabs at the bottom of the Variables window such as Breakpoints, Expressions, etc.. We will take a look at some of these windows in future tutorials. b. The Debug window displays the current state of the stack frame of your application. This will prove to be very helpful when debugging programs with recursive functions. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 33

182 c. The buttons circled below provide you with the basic debugging functionality. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 34

183 Familiarize yourself with the shortcut keys, as they will greatly speed up the debugging process! Command Name Shortcut Key Description Resume F8 Resumes a suspended thread. Terminate - Terminates the selected debug target. Step Into F5 Steps into the highlighted statement. Step Over F6 Steps over the highlighted statement. Execution will continue at the next line either in the same method or (if you are at the end of a method) it will continue in the method from which the current method was called. Step Out F7 Steps out of the current method. *Note: Above table is a modified version of the material from Eclipse s Help file. 6.) Continue on with the debugging process: a. Click on the button or press F8 to allow the application to resume the suspended thread and hit the breakpoint we set earlier. b. Before we step into the sort method, let s take a look at our variables. If we expand the listofnames array, you will notice that each element in the array corresponds to a name read in from the unsorted input file. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 35

184 c. Now click on the button or press F5 to step into the sort method. Once inside the sort method, if you will look in the Debug window, you will notice an extra frame on top of the stack called: 2 sort(char**)() at main.cpp:15 CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 36

185 d. If you click on the frame below called: 1 main() at main.cpp:60 You will notice that you can get view the variables from the main method in the Variables window. Sometimes during debugging, you may need to refer to variables from the calling method and you could easily do this by clicking on the corresponding stack frame. As well, this proves quite handy when debugging through recursive functions. e. Click on the 2 sort(char**)() at main.cpp:15 frame to get back to the sort method and expand the elements variable in the Variables window. It appears that there s only one element in the array! CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 37

186 What happened to all the other elements?? Since this method takes in a pointer to a char array, and we know that there are 20 elements in the array, we can easily display this variable as an array instead of a pointer. f. Right-click on the elements variable and select Display as Array g. Change the Length to 20 and click OK. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 38

187 h. You should now be able to see all 20 elements in the array. i. Now click on the button or press F6 to step through the rest of the sort method. You should notice that the array is slowly sorted into ascending order. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 39

188 j. Once you get tired of stepping through the while/for loops and you understand how the sort works, click on the button or press F7 to step out of this sort method and to return back to the main method. Once in the main method, expand the listofnames variable to verify that the array has been sorted. k. Click on the button or press F8 to resume the rest of the application. After the application terminates, you can switch back to C/C++ Development Perspective and open output.txt to verify that the input file has been sorted correctly. 7.) One of the quirks of the C/C++ debugger is that if you have global variables in your program (variables defined outside your functions and main method), you will not see them appear in the Variables window. So what if you wanted to inspect those variables during debugging? The solution is actually quite simple: a. Start up the application in debug mode by clicking on the bug in the toolbar. b. Click on the button or press F8 to hit the first breakpoint and then click on the button or press F5 to step into the sort method. c. Now that we re in the sort method, to determine the value of the global variable numelements, highlight the variable, right-click and click on Add Expression CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 40

189 d. Verify that the Expression to add is numelements and then click OK. e. You should now see that the global variable numelements has been added to the Expressions window. Repeat the above steps for any other global variable you would like to verify during debugging. CDT (C/C++) Plugin University of Manitoba Tutorial 7 Page 41

190 Eclipse Custom Controls 1, 2 by Shantha Ramachandran, University of Manitoba, Winnipeg, Manitoba, Canada Last revised: October 22, 2003 Overview: Tutorials 2 and 3 described the pre-defined SWT controls. Eclipse developers may also define custom controls that provide additional functionality. There are two different types of custom controls: basic widgets and compound widgets. In this tutorial, we examine a simple example of both types of widgets, and a more complex example which deals with event handling as well. We also briefly examine custom layout managers. Custom Controls in Eclipse: There are a number of Custom Controls that have already been implemented in Eclipse. These include CCombo, CLabel, CTabFolder, SashForm, StyledText and TableTree. To view these controls in action, first install the Examples plugin for Eclipse (see for how to install the Examples). After the Examples have been installed, click on Window -> Show View -> Other From the window that appears, expand SWT Examples and click on SWT Custom Controls. 1 This work was funded by an IBM Eclipse Innovation Grant. 2 Shantha Ramachandran and David Scuse Eclipse Custom Controls University of Manitoba Tutorial 9 Page 1

191 All the Custom Controls identified above are illustrated in the examples plugin. Building Your Own Custom Controls: There are two different ways to create your own controls in Eclipse. The first is by subclassing Canvas, and the second is by subclassing Composite. Canvas is subclassed when you wish to draw basic widgets. This means that you do not need to use any other widgets within your control, but instead will draw the specific elements of your custom control onto a canvas. Composite is subclassed when you wish to group together a number of basic controls to create a larger or more functional control, called a compound widget. Basic Widgets: A custom control should subclass Canvas when the control can be drawn out by itself. The Canvas widget allows a blank working space on which you can draw out your widget. By creating a graphics context, you are provided with a number of methods that allow you to draw your control. A Basic Widget Example: Suppose we need to build a label which has a customizable border. To build this label, which is a basic widget, we first need to subclass Canvas and give the widget a constructor. public class BorderLabel extends Canvas { public BorderLabel(Composite parent, int style) { super(parent, style); In order for the widget to be drawn, we need a PaintListener. A PaintListener detects when the widget needs to be repainted. Our PaintListener has a method, paintcontrol, which will be called when the widget needs redrawing. We can add the PaintListener to the control in the constructor: addpaintlistener(new PaintListener() { public void paintcontrol(paintevent e){ BorderLabel.this.paintControl(e); ); To draw the widget, we need to next create the paintcontrol method. In this method, we create a graphics context which will do all of the drawing. In the following code, we draw Eclipse Custom Controls University of Manitoba Tutorial 9 Page 2

192 a string of text provided by the user, and then draw a rectangle around it. Note that we can set the line style and width of the line before we draw. In this example, text is the string set by the user, and size is the size of the border set by the user. void paintcontrol(paintevent e) { GC gc = e.gc; Point pt = this.getsize(); if (text!= null) { gc.drawstring(text,size,size); if (size > 0) { gc.setlinewidth(size); gc.setlinestyle(style); gc.drawrectangle(0,0,pt.x-size,pt.y-size); Now our widget can be drawn. All we need to do is add access methods that allow the user to set the text and the style of the border for the label. public void settext(string text) { this.text = text; redraw(); public void setbordersize(int size) { this.size = size; redraw(); public void setborderstyle(int style) { this.style = style; redraw(); The redraw method that is called in each set method will queue a paint event for the widget. This event causes the PaintListener to execute its paintcontrol method, and the widget is redrawn. Now lets look at an example that uses our custom BorderLabel widget: Eclipse Custom Controls University of Manitoba Tutorial 9 Page 3

193 Display display = new Display(); Shell shell = new Shell(display); shell.setsize(300,300); BorderLabel borderlabel = new BorderLabel(shell,SWT.NONE); borderlabel.settext("i have a border!"); borderlabel.setbordersize(5); borderlabel.setborderstyle(swt.line_solid); borderlabel.setsize(100,100); borderlabel.setlocation(5,5); shell.open(); while(!shell.isdisposed()){ if(!display.readanddispatch()) display.sleep(); display.dispose(); When we run this program, we get a label with a 5 pixel sold border around the edge. There are many other properties to a custom basic widget that you are free to implement, such as finding the preferred size of the widget. For more information, see the article on the Eclipse website Creating Your Own Widgets Using SWT. Compound Widgets: Compound widgets should be used when you want to create a widget out of other widgets. When you create a compound widget, you need to subclass Composite. Contrary to basic widgets, where you draw the widgets themselves, compound widgets are made up of other basic widgets. No drawing is involved. The Composite holds the other widgets together to form one complex widget. Eclipse Custom Controls University of Manitoba Tutorial 9 Page 4

194 A Compound Widget Example: To illustrate how to create a compound widget, we will create the same widget over again, the BorderLabel. This time, it will be a compound widget. Once again, the first thing we need to do is to create a constructor. In this widget, we will use a label and a group. We can initialize the widgets in the constructor as well. To make this example simplest, we will use a FillLayout to lay the widgets out within the control. public class BorderLabel2 extends Composite { Label label; Group group; public BorderLabel2(Composite parent, int style) { super(parent, style); group = new Group(this, SWT.BORDER); label = new Label(group, SWT.NONE); setlayout(new FillLayout()); group.setlayout(new FillLayout()); In the case of compound widgets, we do not need to draw anything. All we need to finish off the widget is to add set methods. Note that this widget is simpler than the basic widget we just created as we can only set the text, not the border size or style. public void settext(string text) { label.settext(text); layout(true); Let s look at an example that uses our BorderLabel2: Display display = new Display(); Shell shell = new Shell(display); shell.setsize(300,300); BorderLabel2 borderlabel = new BorderLabel2(shell,SWT.NONE); borderlabel.settext("i have a border!"); borderlabel.setsize(100,100); borderlabel.setlocation(5,5); shell.open(); while(!shell.isdisposed()){ if(!display.readanddispatch()) display.sleep(); display.dispose(); Eclipse Custom Controls University of Manitoba Tutorial 9 Page 5

195 This results in the following window: Once again, there are other methods that can be implemented for a compound widget. For example, if you do not wish to use a layout, you can implement a method that will position your children on a resize. For more information on compound widgets, see the article on the Eclipse website Creating Your Own Widgets Using SWT. A Complex Custom Widget: By looking at the previous two examples, you can hopefully differentiate between a basic and a compound widget. You should also be able to create a simple custom control. Next, we will go over an example of a more complex widget that uses event handlers as well. A Zooming Scrolling Widget Example: Suppose that we want to display images on a screen. However, we want these images to be zoomed from small to large. Also, when the images get bigger, we want to be able to scroll the image to see all of it. To do this, we will create a zoomed scrolled canvas widget that subclasses composite. This widget will contain a canvas, scrollbars, and a scale all grouped together in one composite. If you looked at the Eclipse custom controls that have already been created, you will notice that a ScrolledComposite is one of the custom controls available for use. For the next example, we will cheat a little and use the ScrolledComposite custom control within our own custom control, instead of building it from scratch. Eclipse Custom Controls University of Manitoba Tutorial 9 Page 6

196 So, the different components that we will need in our custom control are a scrolled composite, a canvas, a scale and an image. We will also have a label to indicate the level of zoom that is applied to our picture, as well as its width and height. public class ZoomedScrolledCanvas extends Composite { Label zoom; ScrolledComposite comp; Canvas canvas; Scale scale; Image image; int width, height; public ZoomedScrolledCanvas(Composite parent, int style) { super(parent, style); comp = new ScrolledComposite(this, SWT.BORDER SWT.H_SCROLL SWT.V_SCROLL); canvas = new Canvas(comp, 0); scale = new Scale(this, 0); zoom = new Label(this, 0); setlayout(new GridLayout()); In our constructor, we create all our widgets, and give our control a Grid Layout. This will allow us to place the controls in specified positions. We need to do one more thing in our constructor though. We have to initialize and place the widgets. This can be done by calling setup methods from the constructor. We will have a setup method for the composite, the scale and the label. To setup the composite, we simply give it layout data to expand horizontally and vertically within the widget. We also attach the canvas to the composite so that we can draw the image within the scrollbars. public void setupcomp() { comp.setalwaysshowscrollbars(true); comp.setlayoutdata(new GridData(GridData.FILL_BOTH)); comp.setcontent(canvas); layout(true); To setup the scale, we need to specify the maximum, minimum, the increment, and the current selection. We also need to give it layout data. Eclipse Custom Controls University of Manitoba Tutorial 9 Page 7

197 public void setupscale() { scale.setlayoutdata(new GridData(GridData.FILL_HORIZONTAL)); scale.setminimum(0); scale.setmaximum(100); scale.setincrement(10); scale.setselection(50); layout(true); To setup the label, we need to give it layout data and some text. public void setupzoom() { zoom.settext("zoom Factor = 0"); zoom.setlayoutdata(new GridData(GridData.FILL_HORIZONTAL)); layout(true); The next thing we have to do is draw the image onto the canvas. Since the user will be specifying the image to draw, we need a method for setting the image. In this method, we will set the canvas size to the size of the scrolled composite, so the image will appear full size. We need to add a paint listener to draw the image. We will scale it from its full size to the size of the canvas. This is useful, because when we are zooming in and out, we will simply need to change the size of the canvas. When this happens, a paint event will be triggered and the image will be redrawn. Each time it is redrawn, it will take the size of the canvas, and so we are essentially changing the size of the image by zooming in and out. Note that we also have a dispose listener to dispose of the image when the canvas is disposed. public void setimage(string imagestring) { image = new Image(this.getDisplay(), imagestring); canvas.setsize(comp.getsize().x, comp.getsize().y); canvas.setlocation(0,0); canvas.addpaintlistener(new PaintListener() { public void paintcontrol(paintevent e) { GC gc = e.gc; width = comp.getsize().x; height = comp.getsize().y; gc.drawimage(image, 0, 0, image.getbounds().width, image.getbounds().height, 0, 0, canvas.getsize().x, canvas.getsize().y); ); canvas.adddisposelistener(new DisposeListener() { public void widgetdisposed(disposeevent e) { image.dispose(); ); redraw(); Eclipse Custom Controls University of Manitoba Tutorial 9 Page 8

198 Now that we have set up the appearance of our control, we need to add a selection listener to our scale. When the user changes the value of the scale, the image should zoom in or out. In this listener, we calculate a new size based on the zoom factor and resize the canvas. Remember we placed a paint listener on our canvas, so when the canvas is resized in the selection listener, the paint listener will generate a PaintEvent and the image will be drawn to its new size. scale.addselectionlistener(new SelectionAdapter() { public void widgetselected(selectionevent arg0) { zoom.settext("zoom Factor = " + (scale.getselection()-50)); int newwidth = width * (scale.getselection())/50; int newheight = height * (scale.getselection())/50; canvas.setsize(newwidth, newheight); ); This is the last step to creating our custom zoomed scrolled image widget. To see the widget in action, we use it in exactly the same way as we would use any widget. Display display = new Display(); Shell shell = new Shell(display); shell.setsize(400,400); ZoomedScrolledCanvas zsc = new ZoomedScrolledCanvas(shell, SWT.NONE); zsc.setsize(300,300); zsc.setlocation(10,10); zsc.setimage("cats.jpg"); shell.open(); while(!shell.isdisposed()){ if(!display.readanddispatch()) display.sleep(); display.dispose(); We set the size and position of our widget just as we would with a basic widget. The only custom parameter we must set is the image. We set the image to be cats.jpg. The following screen is generated from this code: Eclipse Custom Controls University of Manitoba Tutorial 9 Page 9

199 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: Eclipse Custom Controls University of Manitoba Tutorial 9 Page 10

200 So far, we have described basic custom widgets, compound custom widgets, and event handling associated with custom widgets. There are many things you can do with a custom widget, it all depends on what you need it to do! For more information on how to build custom widgets, download the Eclipse custom widget source code (org.eclipse.swt.custom) or see the online article Creating Your Own Widgets Using SWT. Custom Layouts In the same fashion that you can create custom widgets, you can also create custom layouts to arrange your widgets in a specific manner. Before building a custom layout manager, make sure that the layouts provided by SWT are not sufficient and that a custom layout really is necessary. Building a Simple Layout The following is an example to show how to build a simple layout. This example creates a layout that arranges widgets in a square, so we ll call it the SquareLayout. It will take the widgets on a composite and arrange them row by row in a square format. The widgets will fill the space of the composite. The first thing we need to do is subclass the Layout class. We will add fixed values for the margin and the spacing between the widgets on the composite. public class SquareLayout extends Layout { public static final int MARGIN = 2; public static final int SPACING = 2; // constructor public SquareLayout() { super(); The next thing we will do is override the layout method. This is the method that will actually lay out the widgets on the composite. But before we can know where to lay the child widgets, we need to know the size of the widgets, and the size that the composite is going to be. We will create a method called initialize. In this method, we will figure out how many widgets will be in a row or a column. Since we are creating a square, these numbers are the same. If we find the square root of the total number of children, and round this number up, we will get the number of rows or columns. num = (int) Math.ceil(Math.sqrt(children.length)); Eclipse Custom Controls University of Manitoba Tutorial 9 Page 11

201 Next, we need to calculate the width and height of the composite when all the widgets are laid out on it. Since all the widgets are the same size, we need to find the largest size and the largest height of all the widgets. Then we can just multiply this number by the number of rows and columns to get the total width and height of the composite. All the widgets will grow to be the same size as the largest widget, similar to the FillLayout. sizes = new Point [children.length]; int tempwidth = 0, tempheight = 0; for (int i = 0; i < children.length; i+=num) { sizes[i] = children[i].computesize(swt.default, SWT.DEFAULT,true); partialwidth = Math.max(sizes[i].x, tempwidth); partialheight = Math.max(sizes[i].y, tempheight); // find the height and width for the composite totalwidth = partialwidth*num + (children.length - 1)*SPACING; totalheight = partialheight*num + (children.length - 1)*SPACING; After completing the initialize method, we can now create our layout method. Here, all we need to do is place the widgets, taking margins and spacing into account. Since we know the size that the widgets must be from our initialization, we can simply specify the coordinates of the widgets. One thing to note is that if the composite size is set to be larger than our calculated size, we will choose the larger size and grow the widgets to fit. Rectangle rect = composite.getclientarea(); int x, y = MARGIN; int width = Math.max(partialWidth, rect.width/num-2*margin); int height = Math.max(partialHeight, rect.height/num-2*margin); for (int i = 0; i < children.length; i+=num) { x = MARGIN; for (int j=i; j<children.length && j<i+num; j++) { children[j].setbounds(x, y, width, height); x += (int) width + SPACING; y += height + SPACING; // add 2 for spacing After we have completed this, the only thing left to do is override the ComputeSize method. This will return the preferred size of the composite using your layout. Eclipse Custom Controls University of Manitoba Tutorial 9 Page 12

202 Point computesize(composite composite, int whint, int hhint, Boolean flushcache) { Control children[] = composite.getchildren(); if (flushcache sizes==null sizes.length!=children.length) { initialize(children); // if they have given a width or height, use it // otherwise, use the calculated width and height int width = whint, height = hhint; if (whint == SWT.DEFAULT) width = totalwidth; if (hhint == SWT.DEFAULT) height = totalheight; // account for margin return new Point(width + 2*MARGIN, height + 2*MARGIN); We will create a sample program to test our layout. In this program, we will create four buttons. The layout should arrange the four buttons in a square: Display display = new Display(); Shell shell = new Shell(display); shell.setlayout(new SquareLayout()); Button b1 = new Button(shell, SWT.PUSH); b1.settext("top Left"); Button b2 = new Button(shell, SWT.PUSH); b2.settext("top Right"); Button b3 = new Button(shell, SWT.PUSH); b3.settext("bottom Left"); Button b4 = new Button(shell, SWT.PUSH); b4.settext("bottom Right"); shell.pack(); shell.open(); while(!shell.isdisposed()){ if(!display.readanddispatch()) display.sleep(); display.dispose(); From this we get the following window: Eclipse Custom Controls University of Manitoba Tutorial 9 Page 13

203 When we make this window larger, you can see that the buttons all grow and remain in the same proportions to each other. Note that if the number of widgets is not a perfect square, there will not be an even number of widgets in each row and column: There are many other things you can do with your custom layout. For more information, see the online articles Creating Your Own Widgets Using SWT and Understanding Layouts in SWT. Eclipse Custom Controls University of Manitoba Tutorial 9 Page 14

204 Using JUnit in Eclipse 1, 2 by Christopher Batty, University of Manitoba, Winnipeg, Manitoba, Canada Last revised: October 30, 2003 Overview: In this document, we describe how to use Eclipse s built-in JUnit tools to create unit tests for Java classes. Unit Testing Basics When developing software we need to run our code to verify that it actually works as intended. As the software gets larger and larger, it becomes more likely that introducing a new change will break the existing code. At the same time, verifying all of a program s features by hand is a menial and time-consuming task. To reduce the need for manual testing, we can introduce unit tests which are small snippets of code designed to thoroughly exercise a particular function or class. With unit tests in place, when a change is made to the code we can simply run all the tests to ensure that nothing has been broken. An additional motivation for unit testing is to support test-driven development. Testdriven development involves writing unit tests first, with the actual code coming after. The reasoning is that in order to write complete, valid tests, you must have a solid understanding of how the new class should work, and in particular what its interface will be. Thus, the unit tests provide an executable definition of the class. When you move on to writing the actual code, you just have to fill in implementation, and once the tests are passed, the implementation is complete. In Java, the standard unit testing framework is known as JUnit. It was created by Erich Gamma and Kent Beck, two authors best known for design patterns and extreme Programming, respectively. Eclipse builds come with both JUnit and a plug-in for 1 This work was funded by an IBM Eclipse Innovation Grant. 2 Christopher Batty and David Scuse Using JUnit in Eclipse University of Manitoba Tutorial 10 Page 1

205 creating and working with JUnit tests. As a demonstration, we will use these tools to test a simple class for representing fractions. Creating a Test Case Using Eclipse, import the sample project (JUnitDemo) provided with this tutorial. (A second project, JUnitDemoWithTests, that contains the result of adding JUnit tests is also included.) It contains just SimpleFraction.java, which has functionality for creating, modifying and simplifying a Fraction. The first thing we must do is import junit.jar, so we have access to the testing framework. Right-click on the project name, and choose Properties. In the tree on the left, select Java Build Path. Next, choose Add External JARs and browse to find junit.jar. It will be located in <eclipsedir>\plugins\org.junit_<version number>\junit.jar. Once you successfully import junit.jar, close the Properties page. Now we can create a test for our SimpleFraction class. Right-click the package you wish to place the test in, and choose New, then select Other In the tree on the left, expand the Java branch, and choose JUnit. Then in the list on the right select TestCase. This allows us to create a new test case for SimpleFraction. A Wizard will appear for creating a JUnit TestCase. Click on the Browse button beside Test Class to select the class for testing. In our case it will be the SimpleFraction class, so type in SimpleFraction and select it from the list. Notice that the Test case name is automatically filled in as SimpleFractionTest. Appending Test to the name of the class being tested is the default test case naming scheme in JUnit. Using JUnit in Eclipse University of Manitoba Tutorial 10 Page 2

206 The check-boxes at the bottom allow you to add stubs for additional useful methods. The first is a standard main() function which can be used to run this test individually as an application, rather than as a part of a large suite of tests. The drop-down menu gives you the choice of running with text output, an AWT-based GUI, or a more elaborate Swingbased GUI. This is unnecessary for us since we will be using Eclipse s built-in JUnit tools. The other stubs are for setup() and teardown() functions, which are called before and after each test case. They can be used to reduce redundant code if the tests require the same resources or data. For demonstration purposes, we will use a setup() method to initialize a fraction used by multiple tests. Check setup() and choose Next. The next screen allows you to select which of SimpleFraction s methods you want test stubs generated for. For now we will just test simplify() and getdenominator(), so we check these two boxes and hit Finish. Using JUnit in Eclipse University of Manitoba Tutorial 10 Page 3

207 The class is created with the appropriate method stubs generated for us. All we need to do now is write the tests. Writing the Tests Since getdenominator() is straightforward, we will write testgetdenominator() first. We will create a couple of SimpleFractions and call getdenominator on each. Create two private SimpleFraction member variables like the following: private SimpleFraction f1, f2; In the setup method, add two lines to construct the fractions. f1 = new SimpleFraction(15, 25); f2 = new SimpleFraction(-27, 6); Each time a test method is called, the setup() will run these two lines first, so at the start of each test the fractions will always be 15/25 and -27/6. Now to implement our testgetdenominator() method, add the following code to the method body. int result = f1.getdenominator(); asserttrue("getdenominator() returned " + result + " instead of 25.", result == 25); result = f2.getdenominator(); assertequals(6, result); Since SimpleFractionTest is a subclass of the junit.framework.testcase, it inherits a variety of methods for testing assertions (i.e. conditions that should be true) about the state of variables in the test. These include assertequals, asserttrue/false, Using JUnit in Eclipse University of Manitoba Tutorial 10 Page 4

208 assertsame/notsame, and assertnull/notnull. There is also a fail() method that just causes the current TestCase to fail. These methods generally come in two flavours: a plain version, and a version with a String parameter to provide details about the assertion that failed. In the code above, you can see examples of each. Whenever the assertion in one of the methods fails, the execution of that test method is terminated, and JUnit will record that test as having failed. Next we will implement testsimplify(). f1.simplify(); assertequals(3, f1.getnumerator()); assertequals(5, f1.getdenominator()); This will verify that our simplify() method correctly reduces 15/25 to 3/5. Running the Tests Now that the tests have been written, we would like to run them. The process for running JUnit tests is very similar to that for running regular Java Applications. From the Run menu choose Run Select JUnit in the tree on the left, and hit New. The screen should look like the following, assuming SimpleFractionTest was selected when you opened the Run menu. (If not, simply browse to find SimpleFractionTest.) Next, just choose Run, and the TestCase will be executed. If it ran successfully, you will see a message in the status bar at the bottom of the screen that looks like the following. If the JUnit view is visible, it will display a green bar, indicating a successful test. We will look at the JUnit view in more detail later on. Using JUnit in Eclipse University of Manitoba Tutorial 10 Page 5

209 Debugging a Failed Test Now, let s add another piece of code to our testsimplify() method. f2.simplify(); assertequals(-9, f2.getnumerator()); assertequals(2, f2.getdenominator()); This looks very similar to the previous code in testsimpify(). However, consider what happens when we run the tests again. The JUnit view will be displayed on the left of the screen (if it is not already visible) and it will show a red bar indicating that one or more tests failed. The top part of the view displays the names of the test method(s) that failed. By doubleclicking on the method name, the corresponding method will be opened in the Java editor. Using JUnit in Eclipse University of Manitoba Tutorial 10 Page 6

210 The bottom of the view shows a stack trace of the method calls leading up to the failure. Here we can see that since we used the assertequals method, it gives us a message about what the expected value was versus the value received. Double-clicking on the second line from the top of the stack trace will jump to the specific line at which the failure occurred. The error occurred in the testsimplify() method, and it looks as though the absolute value of the result was correct, but the sign was wrong. By commenting out the failed assertion, we can verify that the sign of the denominator is also reversed from what was expected. A simple fix for this is to check if the denominator is ever negative, and if so negate both numerator and denominator, effectively moving the negative sign to the denominator. The code for this is commented out in the simplify() method of SimpleFraction.java, so we can uncomment it now. if(denominator < 0) { denominator = -denominator; numerator = -numerator; This fix is very straightforward. We can be fairly certain it will correct the specific case in question, but will it break our existing code? Since we have our unit tests in place, we make the change, and run the tests again. This time, they run to completion successfully, and a green bar is displayed in the JUnit view. Both our new and pre-existing test cases work, so we may assume that the fix was correct. This raises an important point about the value of unit testing. A suite of tests is only useful if it is both correct and thorough. You may occasionally have a test case fail only to discover that it is the test case that is flawed and not the code being tested. Similarly, if a change to the code breaks functionality that is not covered by the test cases but is used in your actual application, it will take longer to discover. Meanwhile you may continue to make changes that further break existing code. It is therefore important to keep your unit tests up to date as you write new code. Using JUnit in Eclipse University of Manitoba Tutorial 10 Page 7

211 In the case of our SimpleFraction example above, it would be wise to add some additional simplify() tests with different values and different combinations of negative and positive denominator and numerator to further verify that the change we made behaves as intended. When we later try to add new features to our SimpleFraction class, these existing tests will give us greater confidence in the correctness of any changes. Test Suites Once you have created more than one TestCase, it is useful to be able to group them and run them all together. JUnit has the concept of a TestSuite for doing exactly that. To create a Test Suite in Eclipse, right-click on the package and select New->Other Select JUnit as before, but choose to create a TestSuite rather than a TestCase. By default, all the classes in the package containing the word test will be added to the suite. When you hit Finish, a new class will be created that contains a method that instantiates and returns a TestSuite with all the TestCases you selected. As with individual TestCases, the TestSuite can be launched from the Run menu. You may have noticed the second tab on the JUnit view labeled Hierarchy. This displays the current TestSuite and its contents. In addition to adding individual TestCases to a TestSuite, you can also add TestSuites to a TestSuite. This allows the creation of a more complex, tree-like hierarchy of tests, with TestCases being the leaf nodes and TestSuites Using JUnit in Eclipse University of Manitoba Tutorial 10 Page 8

212 being the internal nodes. It is this hierarchy that is displayed in the Hierarchy view when a JUnit test or suite is run. In our example we have just the single suite containing the SimpleFractionTest class with two test methods. Conclusion Due to its simplicity and usefulness, JUnit has become nearly ubiquitous in the world of Java, and ports of it exist for nearly every language available (e.g. CppUnit, NUnit, HttpUnit, PHPUnit, etc.) If you wish to learn more about JUnit, consider visiting Using JUnit in Eclipse University of Manitoba Tutorial 10 Page 9

213 12 - An Eclipse GUI Builder Overview:... 1 A GUI Builder:... 1 Acquiring the Designer Plug-in:... 2 Installation:... 2 Activating the Designer:... 3 Creating a new SWT/JFace Java Project:... 3 Creating a new SWT Java File:... 4 Parts of the Designer:... 7 Open Definition and Convert Local to Field Buttons Handling Events with the Designer: Adding an Event Listener with the SWT Designer: Deleting an Event Listener with the SWT Designer: Using Layout Managers in the SWT Designer: NullLayout: FillLayout: RowLayout: GridLayout: FormLayout (Professional Version Only): StackLayout (Professional Version Only): BorderLayout (Professional Version Only): FlowLayout (Professional Version Only): GridLayout (AWT) (Professional Version Only): Creating Menus in the SWT Designer (Professional Version Only): Custom Widget Templates (Professional Version Only): Widget Morphing (Professional Version Only): Custom Composites (Professional Version Only): JFace Viewers (Professional Version Only): Custom JFace Dialog Creation: JFace Wizard Page Creation (Professional Version Only): JFace Application Creation (Professional Version Only): Code Generation Options: Type Specific Code Generation Options (Professional Version Only): Additional Features of the Designer: Creating a UI: Two Examples Creating a GUI for an Address Book Application: Creating a new Project: Creating a new SWT Application: Designing the GUI Window: Creating Menus: Creating Event Handlers: Creating an SWT GUI for a Client Billing Application: Taking a Look at the Original GUI: Creating Our Own ClientBillingUI: Creating the Client List Group: An Eclipse GUI Builder University of Manitoba i

214 Creating a Tabbed Folder: The Clients Tab: The Transactions Tab: Creating a Menu: Running the Application: Creating a Swing GUI for the Client Billing Application: Creating the ClientBillingUI: Creating the Client List JPanel: Creating a JTabbedPane: The Clients Tab: The Transactions Tab: Creating a Menu: Running the Application: Summary: An Eclipse GUI Builder University of Manitoba ii

215 12 - An Eclipse GUI Builder 1, 2 by Raphael Enns and Shantha Ramachandran, University of Manitoba, Winnipeg, Manitoba, Canada Last revised: May 21, 2004 Overview: In this tutorial, we describe how to use a GUI Builder plug-in for Eclipse, as well as look at its features. The GUI Builder that we will look at in this tutorial is the Designer created by Instantiations, Inc., and is available at We will be using version of the Designer in this tutorial. A GUI Builder: In the previous tutorials, we have seen that SWT and Eclipse are fairly simple and straightforward to use. One of the most common questions about SWT, however, is Where is the GUI Builder? The answer is that there is no GUI Builder that comes with Eclipse. However, because Eclipse is open source and designed for plug-ins, a GUI Builder plug-in is able to be made and can be integrated right into Eclipse. The Designer is a plug-in that allows you design SWT and Swing GUIs in Eclipse. The Designer is available at A restricted version of the plug-in is available for free download at the above website. There is also a professional version, which includes extra features, that is available for $199 USD. Look at to see a comparison between the free and the professional versions. As of version 2.0 of the Designer, Instantiations includes both SWT and Swing support in the Designer. The SWT part is the same as in previous versions and is called the SWT Designer. The Swing part is called the Swing Designer and is similar to the SWT Designer. There is also a WindowBuilder product in the Designer which is simply both the SWT Designer and the Swing Designer. Since most of the features are the same or similar between the SWT Designer and the Swing Designer, this tutorial will mainly look at features of the SWT Designer. To demonstrate the similarities and the differences between the SWT Designer and the Swing Designer, one of the examples at the end of this tutorial will be done in Swing. 1 This work was funded by an IBM Eclipse Innovation Grant. 2 Raphael Enns, Shantha Ramachandran and David Scuse 12 - An Eclipse GUI Builder University of Manitoba 1

216 Acquiring the Designer Plug-in: You can download the Designer from the website, It can be found in the Download section. Make sure you get the correct file for your version of Eclipse. In order to download the Designer, you must have a username and password. You can get a username and password by registering at the Designer s website. Installation: Once you have downloaded the Designer, installing it is quite simple. First make sure Eclipse is closed. Move the zip file into your Eclipse directory and then unzip the file. It will add three folders to your plugin directory that start with com.swtdesigner. To make sure that the plug-in was successfully installed, start Eclipse. Go to the menu item Help > About Eclipse Platform. Click on the Plug-in Details button, and a list will appear. The Designer and the SWT-Designer Help Plug-in items should appear in the plug-in list. In the case that you would wish to remove the Designer from your computer, the Designer creates a batch file called designer-delete.bat in your Eclipse program directory. Run this file to remove the Designer An Eclipse GUI Builder University of Manitoba 2

217 Activating the Designer: Before you begin using the Designer you have to activate it. To start the activation process, select Window > Preferences inside Eclipse. Select the + beside Designer on the left side of the Preferences window, click on License, and then click on the button that says Registration and Activation. Both SWT and Swing support comes with the Designer product, but depending on your serial number, only one of the three products is activated. For example, if you have a valid serial number for the SWT Designer, you can use the SWT functionality of the Designer, but you will not be able to use the Swing functionality except in evaluation or free mode. If you have a serial number for WindowBuilder, you will have full use of both the SWT and Swing functionality of the Designer. Select the type of Designer that you want to activate, select the desired mode, and then click Next. Follow the directions in the following pages to activate the Designer. Once it has been activated you are ready to start designing GUIs. Creating a new SWT/JFace Java Project: An SWT/JFace Java Project and a regular Java Project are nearly equivalent. They both create a Java project and you can use the Designer with both types. The only difference between an SWT/JFace Java project and a regular Java project is that the SWT/JFace Java project will automatically add the SWT and JFace jar files to the build path An Eclipse GUI Builder University of Manitoba 3

218 To create an SWT/JFace Java Project, select File > New > Project, and then in the resulting window select SWT > SWT/JFace Java Project. Click Next and then create the project the way you would normally create a Java Project. You do not have to add the SWT and JFace jar files to the build path because they are added automatically. Note: To be able to use SWT, the SWT runtime DLL must be accessible by the SWT jar file. For information on how to do this, see the Installing Eclipse tutorial, which can be found at Creating a new SWT Java File: The easiest way to set up a file to use the Designer is to use the Designer Wizard. Select File > New > Other from the menu and select Designer > SWT Application An Eclipse GUI Builder University of Manitoba 4

219 Click Next. In the window that opens, choose the project the file will go in and give the file a name. You can also select which method the SWT code will initially appear in by selecting the appropriate radio button as shown below. Click Finish to create the new file. This will add a file to your project that already has an SWT event loop and a shell created for you. The file should automatically open in the Designer Editor. To open a file that has not been created by the Designer, simply right-click on the file and select Open With > Designer Editor. This will open the file in the Designer Editor in the source view. There are two tabs at the bottom of the editor window labeled Source and Design as shown below. If you click on the Design tab, the file will be displayed in the design view and you will be able to visually design your GUI An Eclipse GUI Builder University of Manitoba 5

220 Two other quick ways to switch between the source and design view are to click on the Switch between source and designer button in the toolbar that is shown below, or simply press F12. Note: If a file was last opened in the Designer Editor, it will continue to open in that editor until a different editor is selected to open the file with. Below is an image of the Designer in the design view for a new file that was created using the SWT Application wizard. Initially the class only has a shell with no controls and no layout. Note: To view the Designer Editor using the full screen, simply double click on the tab of the current file at the top of the editor window An Eclipse GUI Builder University of Manitoba 6

221 Note: The above image is of the professional version of the SWT Designer. The free version looks identical with a few less controls in the Control Palette and a few less items in the editor s toolbar. Parts of the Designer: There are five different parts in the Designer design view: the Method List, the Control Tree, the Control Palette, the Content Pane, and the Inspector. The Method List is a dropdown list of all the methods where controls are created. In this example, the controls are created in the method open. When a method is selected, its controls appear in the Content Pane. The Control Tree shows the hierarchy of controls in the selected method. You can select a control by clicking on it An Eclipse GUI Builder University of Manitoba 7

222 The Control Palette is the palette from which to choose your controls. It contains all the controls that can be added to your GUI with the Designer. Below is shown the Control Palette for the free version on the left and the professional version on the right An Eclipse GUI Builder University of Manitoba 8

223 The Content Pane shows the GUI design as it will look when your application is run. It will also display some extra features to help in editing the design. There is a toolbar at the top of the Content Pane which has buttons for test, cut, copy, paste, delete, as well as several buttons to help position controls. The positioning buttons will only work with controls on a NullLayout. Some of the positioning buttons are only available in the professional version. The Inspector shows all of the properties and events of a selected control and allows you to modify them without going into the code. Select a property by either clicking on the property title or the property value. A property editor is then displayed which allows you to change its value. While editing a property value, you can press Enter to apply the value or press Esc to return to the previous value. If a property s value is not the default value, the property title changes color. Expand or collapse complex properties such as style by clicking on the + or - beside the property title An Eclipse GUI Builder University of Manitoba 9

224 Some properties are selected through a selection property editor. Simply select the value from the list that appears after clicking on the down arrow as shown below. The layout of the Designer s editor can be changed in the Designer s preferences. Select Preferences from the Window menu to open the Preferences window. Expand the Designer item and select Editor Layout. The Editor Layout property page is shown below. You can choose one of three options in the Editor layout dropdown list. The On separate notebooks tabs option is the default option which places the design view and the source view on separate pages. The Above each other with a split pane option will remove the Source and Design tabs and place the design view above the source view in the same editor. The Side by side with a split pane option is similar except it places the design view on the left and the source view on the right. This allows you to view the source while designing in the design view without having to switch back and forth between the design and source views. Since the Designer updates the GUI bidirectionally, making changes in either the design or source view will instantly update the other view. There are four pictures in the Canvas position group, each with a radio button next to it. These options place the Control Tree and the Inspector in different positions in the editor. You can see where each part is by looking at the pictures. The default option is the topleft option where the Control Tree and the Inspector are at the far left of the editor An Eclipse GUI Builder University of Manitoba 10

225 Open Definition and Convert Local to Field Buttons There are two small buttons between the Inspector and the Control Tree. These are Open Definition and Convert Local to Field (or Convert Field to Local if it has already been clicked once). When a control is selected and the Open definition button is pressed, the Designer will switch to the source view and place the cursor on the line where the selected control is instantiated. By default, the Designer generates code using the block style: a control is declared and instantiated inside its own block of code. When a control is declared inside its block of code, it is visible only to its children and itself. When a control is selected and the Convert local to field button is pressed, the Designer will move the declaration of the control from inside its block of code to being a field in the GUI class. When a control is declared as a field, it is visible to everything in that class. If there is a conflict of names when converting a control to a field, the Designer will give the control a unique name. After the Convert local to field button is pressed once it becomes the Convert local to field button. When the button is pressed now, the Designer will move the declaration of the control back inside its block of code. In the examples as the end of this tutorial we will see in more detail how these buttons work. Note: An alternative to the block style of coding is the flat style. Controls are not declared in their own blocks, but are rather declared in the same scope. This is often how a GUI is coded when done by hand. The Designer supports generating code in this style. We will look at how to make the Designer generate code in this style in the Code Generation section of this tutorial. Handling Events with the Designer: Events occur when the user interacts with the UI. The appropriate event-handling code is then executed. In order to know when events occur, event listeners must first be added to your controls. The Designer makes it very easy to add and remove event listeners to your controls An Eclipse GUI Builder University of Manitoba 11

226 Adding an Event Listener with the SWT Designer: There are two ways to add an event listener with the SWT Designer. The first way is through the Inspector. First select a control in either the Control Tree or the Content Pane. Expand the events complex property in the Inspector. Then expand an event and double-click or press Enter on the method you wish to implement. The second way to add an event listener is to simply right-click on a control (either in the Content Pane or in the Control Tree), select Implement > [name of the event] > [name of the method to implement]. A quick way to add event listeners to buttons (including check and radio buttons) and menu items (professional version only) is to simply double-click on the button or menu item. When double-clicked, a selection event listener will be created. Any way you add an event, the SWT Designer will automatically create an event listener for the selected event method. The SWT Designer will then switch to the source view and go directly to the new event handler method. The code generated looks like the following: { final Label label = new Label(shell, SWT.NONE); label.addmouselistener(new MouseAdapter() { public void mousedoubleclick(mouseevent e) { ); label.settext("label"); 12 - An Eclipse GUI Builder University of Manitoba 12

227 There are two ways to quickly return to the event-handling code from the design view. In the Inspector, expand events and then the event. Then double-click or press Enter on the event method to return to the code. The events property value in the Inspector is a list of all the events implemented, and each individual event s property value is the list of methods implemented. If a method has been implemented, its property value is the line number in the source code where its event-handling code begins. The other way to quickly return to the event-handling code is to right-click on a control (either in the Content Pane or in the Control Tree), and then select the menu item for the correct method that was implemented. Shown below is mouse.doubleclick > 32 being selected. In this example, mouse is the event, doubleclick is the event method, and 32 is the line number in the source code on which the method begins. Note: The professional version of the Designer is able to generate an event handler stub method when a new event is created. We will look at how to make the Designer generate this method in the Code Generation section of this tutorial An Eclipse GUI Builder University of Manitoba 13

228 Deleting an Event Listener with the SWT Designer: There is only one way to delete an existing event handler in the SWT Designer. Select a control in either the Content pane or in the Control Tree. In the Inspector expand events and then expand the event. Click on the event method you wish to delete and then press Delete. If there are no other methods that have been implemented for that event, the SWT Designer will also delete the event listener for that event. Using Layout Managers in the SWT Designer: The first step to creating an application is to choose a layout. You can use either the default NullLayout or you can choose one of the layouts listed under the Layouts tab in the Control Palette. FillLayout, RowLayout, and GridLayout are all supported in the free version of the SWT Designer. In addition to the layouts in the free version, the professional version also supports FormLayout, StackLayout, BorderLayout, FlowLayout, and AWT GridLayout. BorderLayout, FlowLayout, and AWT GridLayout are ports of AWT layouts. Below are shown the Layout tabs in the free version (left) and the professional version (right). By default, the SWT Designer does not support designing a GUI using the NullLayout. If no layout is selected for a container, the container in the Content Pane will have red text in the center saying Please choose a layout manager. We will find out how to get rid of this message and how to enable support for the NullLayout in the SWT Designer in the NullLayout section of this tutorial. After you select one of the layouts from the Control Palette, place your mouse over a container in the Content Pane. The area where the layout can be applied will appear highlighted, as shown below. Click the mouse and the layout will be applied. You can check and make sure it was applied by looking at the Inspector. The value of the layout property should now say the name of the layout selected (it will be blank if the NullLayout is used) An Eclipse GUI Builder University of Manitoba 14

229 To remove a layout from a container, select the container in either the Content Pane or in the Control Tree, click on the layout property in the Inspector, and then press Delete. Another way to remove a layout is to right-click on the container holding the layout in either the Content Pane or Control Tree and select Delete Layout. When a layout is removed from a container, the SWT Designer converts the layout to an equivalent NullLayout by using the setbounds() method call for each control in the container. This means that after you delete a layout, the controls will be in the same position and the same size as before, even though the layout is now the NullLayout. To switch from one layout to another on a container that already has one or more controls on it, you must first delete the current layout and then apply the new layout. If the container has no controls on it, you are able to change layouts without deleting the current layout first, unless the current layout is a FormLayout or a BorderLayout. Adding controls to a container is similar to placing a layout. Simply select the desired control in the Control Palette, move your mouse to the desired area in the Content Pane, and click to place the control. A control can also be added by placing the control on the Control Tree. To delete a control, simply select it and press Delete. More specific examples of how to place controls for each layout are shown in the individual layout sections. For more information on SWT layout managers, see the tutorial Eclipse Layouts. NullLayout: In order to begin designing applications using the NullLayout, you must first enable it in the SWT Designer. To do this, go to the menu item Window > Preferences. On the left side of the Preferences window, expand Designer and click on SWT. On the right side, check Allow absolute/null layout (setbounds()). Then click OK An Eclipse GUI Builder University of Manitoba 15

230 The NullLayout is very easy to use. You simply have to place and size a control exactly as you want it. One downfall with using the NullLayout is that you may lose some portability. Though your application may display correctly on your platform and screen resolution, on another platform, or on a different screen resolution, it may not display correctly. The NullLayout has no layout properties to set. To place a control on a shell with a NullLayout, select a control from the Control Palette, click on the shell to set the top-left corner of the control, and then drag to set the size of the control. The new control will then be placed on the area of the shell that you selected. To move a control, simply click on the control and drag it to where you want it. To resize a control, select the control either in the Content Pane or in the Control Tree. Then click and drag the handles that are around the edges of the control. To delete a control, simply select the control and press Delete. When you create, move, or resize a control that is on a NullLayout, a grid is shown. The edges of the control you are creating, moving, or resizing will always snap to the grid points. The grid helps you to place the controls evenly. A button being moved on a NullLayout is shown below An Eclipse GUI Builder University of Manitoba 16

231 You are able to change the distance between the points on the grid. To do this, select Preferences from the Window menu. Expand the Designer item and select the General item. Setting the Grid step value will set the distance between the points. You can enter a value between 1 and 100. This value is the number of pixels between points. The default Grid step value is 5. There are several buttons on the toolbar above the Content Pane that can be used to align controls on a NullLayout. Most of the buttons are only available in the professional version of the Designer. Only the two buttons on the far right are also available in the free version. The buttons on the far right are Center horizontally in window and Center vertically in window. To use them, select a control on a NullLayout and press one of the buttons. The selected control is now centered in the container. To enable the other buttons, multiple controls must be selected. When multiple controls are selected and one of the alignment buttons is pressed, the controls will line up their edges or centers, depending on which button is pressed, to one of the selected controls. Generally the selected controls will always be aligned to the selected control highest in the z-order. The only way to align controls to a specific control regardless of its location in the z-order is to select the control you wish to align to, hold down Ctrl or Shift, and then in the Content Pane select the controls you wish to align. If you then press one of the alignment buttons, the other controls will align themselves to the first control selected. Once an alignment button has been pressed, any subsequent presses to any alignment button will return to aligning the selected controls to the control highest in the z-order. Below is shown a shell with a NullLayout which has several controls placed in it: Note: You cannot change the size and position of a control in the Inspector using NullLayout. To do this you must go into the source code and modify the setbounds() method call or move and resize the control on the Content Pane An Eclipse GUI Builder University of Manitoba 17

232 Note: If there is any container which uses a layout other than a NullLayout, and that container s parent uses the NullLayout, it will display controls as if it had a NullLayout. That means that every control still needs a setbounds() call even though the container it is on does not use the NullLayout. This makes using a different layout manager on the container to be useless. This is why you should either use the NullLayout for everything in an application, or do not use it at all. FillLayout: FillLayout is the easiest layout manager to use, both with and without the SWT Designer. It places your controls in either a single row or single column. FillLayout has only one style property to set dir, which can be horizontal or vertical. There are two ways to set this style. The first is through the Inspector. Select the container in the Control Tree and then expand the layout property and the style property. The property value of the dir property can be set to either horizontal or vertical. The second way to set this is within the Content Pane. When a control in a container with FillLayout is selected, a small switch appears in the top right corner of the container indicating which direction the layout is in. Clicking on this switch changes the direction. In the example below, the switch is indicating a horizontal FillLayout, as there are two controls side-by-side, horizontally. For a vertical FillLayout, two controls are pictured one on top of the other, vertically. To add the first control to a container using FillLayout, select a control from the Control Palette and click anywhere in the container. To add more controls, select a control from the Control Palette, and then place the cursor to the left or right of a control already placed (if the dir property is horizontal), or to the top or bottom of a control (if the dir property is vertical). A small red line will appear where the control is to be placed, as shown below An Eclipse GUI Builder University of Manitoba 18

233 If no red line appears when trying to place a control, make sure that the container that the control will be placed in is selected in the Control Tree. To move a control, simply click and drag the control to the desired position. RowLayout: Using RowLayout is similar to FillLayout in that you can set a dir property to horizontal or vertical. However, RowLayout does have a few more properties that can be set. These can all be set using the Inspector. If the justify property is set to true, the controls will be evenly spaced out across the screen either horizontally or vertically depending on the dir property. The margin properties set how many pixels away from the edges of the container to place to controls. When pack is true, all the controls are their natural size. When pack is false, all the controls are the same size. The spacing property sets how many pixels are to be between each control. When wrap is true, the controls are wrapped onto the next line if they cannot fit all on one line. When placing a control onto the container, a red line will appear where the control will be placed. By moving your mouse around, you can specify exactly where in the layout you wish to place another control. When a control placed on a container using RowLayout is selected, it will have three small square handles. The handles are on the bottom edge, right edge, and bottom-right corner, as shown below. If you click and drag these handles, you can resize individual controls An Eclipse GUI Builder University of Manitoba 19

234 GridLayout: GridLayout is significantly different from FillLayout and RowLayout because of the amount of layout data that can be manipulated. There are a number of properties that appear in the Inspector that can help you configure the GridLayout. The most important one is numcolumns, which specifies how many columns are in your grid and therefore determines the size of the grid. The horizontalspacing and verticalspacing properties specify how many pixels are between each control. When the makecolumnsequalwidth property is set to true, it sets each column in the grid to be equal in width. You can also set the makecolumnsequalwidth and numcolumns properties by rightclicking on the container in either the Content Pane or the Control Tree. In the following example, there are two columns. You can see how each control in the grid has vertical and horizontal alignment buttons. By clicking on these buttons you can quickly and easily change the alignment of the controls, to beginning, ending, center, or fill An Eclipse GUI Builder University of Manitoba 20

235 You can also change the alignment simply by clicking on a control and dragging it through four different areas. A tool tip will appear indicating which type of alignment you are currently in. Simply drag the control to where you want it to be. To change the vertical alignment, press Ctrl while dragging the control through the different areas. When you press the Ctrl key on your keyboard, the arrows on the alignment buttons disappear and they change into grab buttons. By holding down the Ctrl key and clicking on a grab button, the control will switch between grabbing excess space, and not grabbing excess space. Horizontal and vertical span can be set to span one or more columns or rows by dragging the handles of the controls. You can also make a control grab horizontally or vertically by right-clicking on the control and selecting Grab horizontal or Grab vertical from the popup menu. To facilitate these processes even more, there is a series of hot keys that can be used to set alignment and grab properties. To change a property, simply select a control and press the hot key on your keyboard. Here are the implemented hot keys: l set horizontal alignment to left r set horizontal alignment to right c set horizontal alignment to center f set horizontal alignment to fill t set vertical alignment to top b set vertical alignment to bottom C set vertical alignment to center F set vertical alignment to fill h set horizontal grab on/off v set vertical grab on/off o set horizontal and vertical alignments to fill and switch grab on/off All of these properties can also be modified in the Inspector under the layoutdata property of a control as shown below An Eclipse GUI Builder University of Manitoba 21

236 As with FillLayout and RowLayout, when you are placing an item on the shell, a red line will appear to indicate where on the grid your new control will be placed. Once a control is placed, the layoutdata properties will appear in the Inspector for the control. FormLayout (Professional Version Only): Though the FormLayout is one of the most complicated layouts, it is also one of the most useful and powerful. By using the FormLayout, you are able to configure each side of a control to snap to window margins, percentage points, and even to the sides of other controls. Controls can be freely placed on a container with FormLayout. They can be freely moved and resized as well. The SWT Designer fully supports the FormLayout and you can easily configure the layout graphically. The SWT Designer has dynamic snap points at the window margins, at predefined percentage points, and near other controls. By dragging a control near these snap points, the control will be set to the snap point and will dynamically move and resize to stay consistent to the snap points. The free version of the SWT Designer does have some limited FormLayout support to allow you to see how your application will look. You are not able to add FormLayout to a container in the SWT Designer, but you are able to properly view a GUI using FormLayout. You are also able to modify the layout properties in the Inspector of controls placed on a FormLayout. The snap points in the Content Pane are only available in the professional version. Placing the FormLayout on a container is the same as other layouts. Simply select FormLayout from the Control Palette and place it on the container. The layout itself does not have any properties. Each control on a container using FormLayout has configuration data in the form of FormData, which can be accessed in the layoutdata property in the Inspector. To place a control, simply select a control from the Control Palette and click anywhere on the container. If you just release the mouse button right where you clicked it, the control will be created at its natural size with its top-left corner exactly where you clicked. If you drag the control after clicking, you can specify the size of the control An Eclipse GUI Builder University of Manitoba 22

237 While placing the control, you may see some tool tips on the right and bottom of the container with a number in them. These show the number of pixels from the top or left edge of the container. Like the NullLayout, the FormLayout displays a grid when creating, moving, or sizing controls. If you select a control place on a FormLayout and expand the layoutdata property in the Inspector, you should see four complex properties called left, right, top, and bottom. These are FormLayout settings for each of the four sides of the selected control. All of the sides have the same properties. If you select the control property, a button with three dots will appear in the property editor. If you click this button, a window pops up with a list of all the controls that the selected control can snap to. The align property allows you to set which side of the control listed in the control property the selected control is snapped to. The align property can also be set to center or default. Setting the align property to center places the snap point in the center of the control listed in the control property. Setting the align property to default sets the snap point to the side of control listed in the control property opposite the side of the selected control. For example, if you were changing the left side of a control and selected a default alignment, the left side of the control would snap to the right side of the control listed in the control property An Eclipse GUI Builder University of Manitoba 23

238 If a side of the selected control is snapped to another control, the offset property specifies the number of pixels the two sides of the controls are from each other from the perspective of the control listed under the control property. For example, let s say that the selected control is to the right of the control that it is snapped to and the left side of the selected control is snapped to the right side of the other control. If the two controls have a 50 pixel offset between them, the offset property of the left side of the selected control would be 50. Note: Not all controls are necessarily listed in the window of controls to snap to. The only controls that are listed are the siblings of the control (controls created in the same container) that are higher in the z-order (higher up in the Control Tree), any sibling of a parent control (the parent can be any number of levels deep), and any parent control (to any number of levels). The numerator property is a percentage. Its value can be an integer from 0 to 100, inclusive. By setting this value, the selected side of a control will snap to this percentage point. The value 0 corresponds to the left edge (when modifying the left or right sides of a control) or the top edge (when modifying the top or bottom sides of a control) of the container holding the control. The value 100 corresponds to the right edge (when modifying the left or right sides of a control) or the bottom edge (when modifying the top or bottom sides of a control) of the container holding the control. If a side of the selected control is snapped to a percentage point, the offset property specifies the number of pixels the side of the control is from the percentage point from the perspective of the percentage point. For example, if the left side of a control has a numerator value of 50 and an offset value of 10, the control is 10 pixels to the right of the center of the container. Note: A side of a control can be snapped to either another control or to a percentage point. If you set the control property for a side of a control, the numerator property is cleared. Likewise, if the numerator property is set, the control and align properties are cleared. Although you can fully modify the snap points of all four sides of a control in the Inspector, it is often a lot easier to do this in the Content Pane. The SWT Designer allows you easily set up snap points graphically. In the Content Pane, you will notice a small button on each side of your control. When clicked, these buttons will bring up a popup menu with some more buttons. These buttons change what the side of the control is snapped to An Eclipse GUI Builder University of Manitoba 24

239 The two buttons in the popup menu that have an arrow and a number sign specify that the side of the control is always to be the same number of pixels from the edge of the container that the arrow is pointing to. The button with the percent sign specifies that the side of the control is always to be a specific percentage away from the left or top edge of the container. The button that shows one rectangle pointing to another rectangle specifies that the side of the control is always to be the same number of pixels from the edge of another control. When this button is clicked, the window with the list of all the controls that the selected control can snap on to appears. The button removes any snap points for that side. Below is shown a button with each side having a different type of snap point. The left side snaps to a fixed offset from the left window edge. The top side snaps to a percentage point from the top edge of the window. The right side snaps to another control. The bottom side snaps to a fixed offset from a percentage point. To quickly set snap points using some often used settings, simply right-click on a control, select Attachment style, and then select the style that you want to use An Eclipse GUI Builder University of Manitoba 25

240 There are five sections in the menu. The first section attaches all four sides using fixed offsets from two of the container s sides. The second section attaches all four sides using fixed offsets from three of the container s sides. The third section attaches each side to the corresponding side of the container. The fourth section attaches two of the sides to fixed offsets from two of the container s sides and attaches the other two sides to percentage offsets from the container s sides. The fifth section attaches three of the sides to fixed offsets from three of the container s sides and attaches the fourth side to a percentage offset from the container s side. You can get all the attachment styles that appear in the menu above in a small Layout Assistant window. The button to open this window is in Eclipse s main toolbar. Once you have clicked the button, the following window appears. If no controls are selected or if you are not using FormLayout, the Layout Assistant window will say Parent does not provide any layout assistance. The FormLayout also supports the alignment buttons on the toolbar above the Content Pane that we looked at in the NullLayout section of this tutorial. These buttons function similarly when using the FormLayout as when using the NullLayout. Another way to access the alignment buttons while using FormLayout is by clicking the Alignment tab in the Layout Assistant window. You can also set the snap points to predefined offsets and percentage points. To see what these values are and how to change them, we will go to the SWT Designer s FormLayout properties page. To get there, select Window > Preferences, then select Designer > SWT > FormLayout from the pane on the left. You should see the following page: 12 - An Eclipse GUI Builder University of Manitoba 26

241 When Keep attachment style during alignment is checked, the attachment styles for a control do not change when the alignment buttons are used. If it is unchecked, the attachment styles of the sides of the controls you are aligning will be changed to the alignment styles of the control you are aligning to. The Suppress dropdown box specifies when snap points will not be displayed. The default value is When Ctrl key pressed. This means that when you hold down the Ctrl key, snap points will not be displayed on the Content Pane. The snap point sensitivity is the maximum number of pixels that the control can be away from the snap point for the control to be grabbed by the snap point. If this value is set to -1, no snap points will be displayed. Snap point settings can be set independently for horizontal and vertical operations. There are snap points at given offsets from the window margin, from each default percentage point, and from each widget. If a value of -1 is given for any of these, that particular snap point attachment will be disabled. Default percentage snap points can be set as well. Doing this creates snap points anywhere in a container. The values can be integers from 1 to 99 inclusive (50 would be the center of the container). To show how the default percentage snap points work, we will create a horizontal and a vertical percentage point, each with a value of 50. If you create a control and move it around, you will see lines appearing at certain places. These are the snap points that are defined in the FormLayout property page. Every control is broken up into four quadrants. If you move your mouse over a quadrant, there will be a line on the outside edges of that quadrant as shown below. When you move the control by dragging it, the two sides that have the line will be the only sides able to snap to a snap point An Eclipse GUI Builder University of Manitoba 27

242 Snap points are shown as gray lines for percent lines and blue lines for offset lines. The colors for these lines can be changed in the property page. To snap to a preset snap point, move the mouse into the proper quadrant of the control, and drag the control near the snap points. Lines will appear and the control will be grabbed by the snap points when you drop it. Above there are two blue lines. The horizontal blue line is the window margin offset, which is set to 5 pixels. The vertical blue line is the 5 pixel offset from the 50 percentage snap point that we added to the properties page. The gray line is the actual 50 percentage snap point. There is also a tool tip on the bottom displaying what the horizontal snap point is. If the button above is dropped where it is shown, the right side of the button will always be 5 pixels left of the center of the window, and the top of the button will always be 5 pixels below the top of the window. When you drag the handles of a control to resize it, the snap points will also appear and you can snap to them. Dragging a control near another control that is higher in the z-order (higher up in the Control Tree) will also display snap points. As shown below, the two blue lines are the 5 pixel offsets from the sides of the other control, while the gray lines are the snap points formed by the sides of the other control. Resizing a control also displays snap points to other controls. If a control is moved or resized and it has other controls that are snapped to it, the other controls will also move or resize to stay consistent with the snap points An Eclipse GUI Builder University of Manitoba 28

243 There are also hot keys to quickly set the majority of snap points. They are more complicated than the hot keys for the GridLayout, but it can be worthwhile to understand them. To use the hot keys, you need to press a sequence of keys. The case of the letters does not matter. Below is a list of the key presses. The information was taken from the Designer s documentation. L, R, T, B select the side you with to work with (Left, Right, Top, Bottom) M set the attachment to the margin A work with Absolute pixels L, R, T, B set offset from the Left, Right, Top, or Bottom of parent several digits representing the pixel offset followed by Enter several digits representing the pixel offset followed by Enter (if no side of the parent is given, Left or Top is used) P work with Percentage points A uses a zero offset one digit followed by Enter or two digits representing the percent S uses the negative of the offset for the attachment one digit followed by Enter or two digits representing the percent one digit followed by Enter or two digits representing the percent (this uses the offset for the attachment) The above may be a little bit unclear, so below is a table of the keys. Start in the left column of the table and work your way right. If a step has several letters separated by commas, you can choose one of the options. nothing refers to not pressing any keys on that step. Look above to get the meaning for a sequence of keys. M L, R, T, B A L, R, T, B, nothing Digits Enter P A, S, nothing Digit Digit Enter 12 - An Eclipse GUI Builder University of Manitoba 29

244 As you start using the FormLayout, you will find that it is very powerful. Using the SWT Designer, it is also very easy to use. The SWT Designer allows you to modify FormData settings in several ways, allowing you to use the way that works the best for a given situation. For more information on FillLayout, RowLayout, GridLayout, and FormLayout, see the tutorial Eclipse Layouts. StackLayout (Professional Version Only): StackLayout is not one of the standard layouts in SWT although it does come with SWT. StackLayout resizes all controls to fill the container. Therefore only one control is visible at a given time. This layout may be used when you want two or more controls to be in the same location, with only one of them being displayed at a time. A container using a StackLayout can be thought of as a TabFolder, except instead of switching pages by clicking on tabs, you have to specify your own actions to switch controls. The free version of the SWT Designer can display containers using StackLayout and can modify layout properties, but it cannot place a StackLayout on a container. Any number of controls can be placed on a container using StackLayout. Only the top control is displayed. When the application is run, the control that is on top in the design view is going to be the top control. There are two layout properties in the Inspector that you can modify. They are the marginheight and the marginwidth. These set the number of pixels the controls are from the edges of the container. There are two small buttons that appear in the Content Pane that allow you to change which control is displayed. To access them, click on a control that is on a StackLayout. The buttons are shown below. Clicking on the arrow pointing up will switch to the control higher up in the z-order. Clicking on the arrow pointing down will likewise switch to the control lower down in the z-order. Once the top or bottom control in the z-order is reached, it will wrap around An Eclipse GUI Builder University of Manitoba 30

245 Another way to select a control is to simply select a control in the Control Tree. That control will be displayed in the Content Pane and will be the control that is displayed when the application is run. If you wish to switch controls when an event occurs, add these lines to the event handler: stacklayout.topcontrol = control; container.layout(); where stacklayout is the variable name for the StackLayout, control is the name of the control that you want to be placed on top, and container is the container on which the StackLayout is placed on. The top line sets the appropriate control to the top and the bottom line redraws the container. If the container is not redrawn, the top control will not switch until you perform an operation that forces a redraw such as resizing the window. If you wish to switch controls when an event is triggered by a control outside of the container using StackLayout, you will have to convert several items to fields. The items to be converted to fields are the container using the StackLayout, the controls in the container, and the StackLayout. Converting the container and the controls in it to a field is easy. Simply select each one in turn and click on the Convert local to field button. Converting the StackLayout to a field is a little bit harder because there is no StackLayout item to select to use the Convert local to field button with. You will have to edit the source code. Remove final StackLayout from the line that instantiates stacklayout and add the following line to the rest of the fields at the top of the class: private StackLayout stacklayout; Now you can access stacklayout from anywhere in the class. If you only wish to access it from the same method, an alternate way is to move the whole instantiation line of code outside of any blocks and to the top of the method. Now you can switch the top control exactly like we did before. BorderLayout (Professional Version Only): BorderLayout is an AWT layout that has been ported over to SWT. BorderLayout allows you to place controls on five specific spots on the container. These spots are the center and the four edges. When a BorderLayout is placed on a container, there are a couple of properties listed under layout in the Inspector. The hgap and vgap properties are the number of horizontal and vertical pixels that are between controls An Eclipse GUI Builder University of Manitoba 31

246 When you try to place a control on a BorderLayout in the Content Pane, a grid will appear showing the different areas that you can place the control. Once a control has been placed, the spot where it has been placed is a different color. You are not able to place another control in that spot. When a control that is placed on a BorderLayout is selected, it will have a layoutdata property. You can set this property to north, south, west, east, and center. North refers to the top of the container, south is the bottom, west is the left, east is the right, and center is the center. Only one control can be displayed in any of the five spots at one time. A shell using BorderLayout with the hgap set to 5, the vgap set to 10, and with a button in each spot looks like the following: 12 - An Eclipse GUI Builder University of Manitoba 32

247 FlowLayout (Professional Version Only): FlowLayout is also an AWT layout that has been ported over to SWT. It is similar to RowLayout in that it places controls in rows starting from the top. Once a row is full, it places controls on the next row. Unlike RowLayout, FlowLayout is able to use different alignments. The controls on a FlowLayout are always their natural size and cannot be resized. You can change the alignment, horizontal gap (hgap) and vertical gap (vgap) properties of the layout in the Inspector. The alignment property can be set to left, center, right, leading, or trailing. Leading is the same as left on a left-to-right orientation, and trailing is the same as right on a left-toright orientation. The horizontal and vertical gaps are the number of pixels horizontally and vertically between each control. A shell using a FlowLayout with center alignment looks like the following: 12 - An Eclipse GUI Builder University of Manitoba 33

248 GridLayout (AWT) (Professional Version Only): GridLayout is an AWT layout that has been ported over to SWT. The AWT GridLayout is somewhat similar to the SWT GridLayout, but it is more restricted. Under the layout property in the Inspector, you can set the number of columns, the number of rows, and the gaps between controls. You may notice that the layout property s value is the fully qualified name of GridLayout. This is so that the AWT GridLayout will not conflict with the SWT GridLayout. The AWT GridLayout forces the columns to have equal width and the rows to have equal height. The largest number of controls that can be visible on a container at one time is the number of columns multiplied by the number of rows. Any more controls that are added will not be visible. Below is shown a shell using the AWT GridLayout with four columns and three rows. All twelve cells in the grid have a control in them and they are all equal in size. Creating Menus in the SWT Designer (Professional Version Only): Menus are a must for just about all GUIs. Using the SWT Designer, it is quick and painless to create menu bars and popup menus. The free version of the Designer is able to display already created menus, but it does not have support to create them. We will look at creating menus manually in an example later in this tutorial for users of the free version of the Designer. To create a menu bar on your shell, select MenuBar from the Control Palette, and then place it on your shell in the Content Pane. Each shell can have at most one MenuBar, and the only place that you can put a MenuBar is directly on a shell. A particular menu will only be displayed on the shell on which it was created. After the MenuBar is placed, you should see a blank menu bar across the top of your shell in the Content Pane An Eclipse GUI Builder University of Manitoba 34

249 To add individual menus to the menu bar, select Menu from the Control Palette, and then place it on the menu bar. A menu is the same as a menu item that has its cascade style property always set to true. To add a menu item to a menu, select the dropdown menu and add a MenuItem to the dropdown menu that is displayed. If you want to make a submenu, add a Menu to the menu or set a menu item s cascade property to true. Menu items can also be a check or radio style. To create a checkbox or radio button menu item, select CheckBoxMenu or RadioButtonMenu from the Control Palette and add it to a menu. CheckBoxMenus and RadioButtonMenus are MenuItems with their style set to check or radio. To make a check or radio menu item initially be selected, set the selection property to true in the Inspector for that menu item. You can also add an image to a menu item. Simply select the menu item, click on the image property in the Inspector, click on the button that appears in the property editor, and select an image. For more information on selecting images, see the Additional Features of the Designer section of this tutorial. The Designer will only show the top part of the image if the image is too big, but when the program is run, it will display the entire image. Setting the text of a menu item is the same as setting the text of any other control. In the Inspector, set the text property to the desired text. By placing an ampersand (&) before a letter in the text property, you will create a mnemonic for that menu item. On most platforms, the letter after the ampersand will be underlined when you run the program. When you press this key when the menu is displayed, the menu item will be selected An Eclipse GUI Builder University of Manitoba 35

250 To quickly test what the menu will look like in your application, use the Designer s test feature. To use this feature, click on the test button in the toolbar above the Content Pane or right-click in the Content Pane and select Test. In addition to creating a menu bar, you can also create a popup menu for any control, including the shell. Simply select PopupMenu from the Control palette, move it over to the desired control in the Content Pane and click to place it on that control. Only one popup menu can be placed on a control. After a popup menu is placed on a control, a little menu icon will appear on that control as shown below. If you click on that icon, the popup menu is displayed. Adding menu items to the popup menu is identical to adding menu items to the dropdown menus on the menu bar. To see your popup menu at work, use the Designer s test feature and right-click on the control you added the popup menu to. The menu you created will now appear. As you have seen above, creating menus in the SWT Designer is very quick and easy. Adding a selection event handler for the menu item is also easy. Simply double-click a menu item and a selection event handler will be created for you. For more information on menus, see the tutorial Advanced SWT Widgets An Eclipse GUI Builder University of Manitoba 36

251 Custom Widget Templates (Professional Version Only): Sometimes you might want to place several controls of the same type, each with the same properties. You could place each control and set their properties individually, or you could select multiple controls and then set all their properties at once as will be shown later in this tutorial, or you can create a custom widget template for that type of control. Custom widget templates allow you to save your own default properties for a control type. When a new control of that type is created, it will have the same properties that you set up. For example, if you wanted all of your check buttons to have a green foreground and a black background, you could set up a template to create all your check buttons like that. In order to create a template, a control must first be placed. Set the properties of the control to the desired settings, then right-click on the control in either the Content Pane or the Control Tree and select Template > Save template. Now any control of that type that is created will have the properties from the template. To remove a template for a type of control, right-click on any control of that type and select Template > Clear template. Now if any new controls of that type are added, they will be created with the default properties. Clearing the template will not affect already placed controls. You can also apply a template to any existing controls by right-clicking on a control whose type has a template and selecting Template > Apply template. The control will now have the properties saved in the template. There are several properties that are not saved in a template. They are the events, layoutdata, variable name, image, and items properties. The scope of a control (whether it is a local or a field) is also not saved. The templates can be used in different files. The templates are saved even if you close Eclipse. You can create at most one template for each type of control An Eclipse GUI Builder University of Manitoba 37

252 Widget Morphing (Professional Version Only): It can be frustrating to suddenly want a group instead of a composite after you have already completed the design of the composite. It is very easy to remedy this using the professional version of the Designer. The Designer allows you to morph similar controls from one type to another. When a control is morphed from one type to another, the properties that are the same between the two types are kept. This allows quick design changes without having to recreate all the controls. To morph a control from one type to another, right-click on the control and select a control type to morph to from the Morphing cascading menu as shown below. There are numerous control types that are able to morph into other types. Below is a list of the morphs that are possible with SWT controls. A bidirectional arrow means that the morph can go both ways. A list of control types with bidirectional arrows between them means that one of the types can morph to any of the other types. Composite Group TabFolder CTabFolder Button Check Button Radio Button Label CLabel Text Styled Text Combo CCombo Combo CCombo List Canvas Composite TreeViewer CheckboxTreeViewer ListViewer Combo, CCombo TextViewer Text, Combo, CCombo Custom Composites (Professional Version Only): The professional version of the SWT Designer allows you to add frames to your application. Another name for a frame is custom composite. A frame is a custom class that extends composite or group. With the SWT Designer, you can easily create your own frame and add it to your application An Eclipse GUI Builder University of Manitoba 38

253 To create an SWT Frame using the SWT Designer, select File > New > Other. In the window that appears, select Designer on the left pane, select SWT Frame on the right pane, and then click Next. Enter a package name and the name for the class. The SWT Designer will not be able to use a frame that is in the default package, so you must specify a package. Select the desired frame superclass and click Finish to create your class. In the Content Pane, you should see a blank composite or group: You can add a layout and controls to the frame and edit its properties exactly like you would with a regular composite or group created in an SWT Application. If you click on the Designer s test button, your frame will be displayed in a shell An Eclipse GUI Builder University of Manitoba 39

254 After you have created your frame, you can place it in an SWT Application. To add a frame, select Frame from the Control Palette. It is listed close to the top. Select the frame you wish to add from the window that appears and click OK. Now place your frame just like you would place a normal control. Your frame acts like a singular control. When you click on the frame, you can edit its properties, which are the same properties as that of a composite or group. However, you cannot select controls inside of or add controls to the frame in your SWT Application. You can only edit the controls inside the frame if you open the class for the frame. Below is shown a frame added to an SWT Application An Eclipse GUI Builder University of Manitoba 40

255 JFace Viewers (Professional Version Only): JFace extends several controls such as lists and trees to make them even more powerful. You are able to link objects with JFace viewers instead of just displaying strings of text or images. You are also able to easily sort and filter the items to be displayed. The SWT Designer supports creating all the standard JFace viewers. These are TableViewer, CheckboxTableViewer, TableTreeViewer, TreeViewer, CheckboxTreeViewer, and ListViewer. The SWT Designer also supports the TextViewer, but this viewer is considerably different than the other viewers. To use the TextViewer, jfacetext.jar needs to be added to the project s build path. We will not look at the TextViewer in this tutorial. To create a JFace viewer in the SWT Designer, select a viewer from the Control Palette under the JFace category and place the viewer on the application window. You can place JFace viewers anywhere you can place a regular SWT control. The viewers look just like the type of control that they extend. For example, a ListViewer looks like a List and a CheckboxTreeViewer looked like a Tree with its check style set. However, the viewers have several properties in addition to the properties of the control they extend. Below is shown the properties of a TreeViewer. The properties of the control that the viewer extends are under the control property. In this case, the properties of a Tree are listed under the control property. The contentprovider, labelprovider, and sorter properties set the classes that contain each provider or sorter. There are two ways to set the contentprovider, labelprovider, and sorter properties. If you double-click any of these properties in the Inspector, a nested class is created for that property. The nested class will extend and implement any classes and interfaces that are usually used for the selected viewer. Stubs for all the necessary methods are also generated. The providers and the sorter are then set to the viewer by the following code: treeviewer.setsorter(new Sorter()); treeviewer.setlabelprovider(new TreeLabelProvider()); treeviewer.setcontentprovider(new TreeContentProvider()); 12 - An Eclipse GUI Builder University of Manitoba 41

256 If you want to use top-level classes as your providers and sorter, simply change the previous code to pass instances of the top-level classes as parameters in the setsorter(), setlabelprovider(), and setcontentprovider() methods. For more information on creating JFace Viewers, see the JFace tutorial. To learn more specifically about TableViewers and TreeViewers, view the articles at the following links. Custom JFace Dialog Creation: The only JFace element that is fully supported in the free version of the SWT Designer is the JFace dialog. The SWT Designer allows you to graphically create a custom JFace dialog. To create a custom dialog select File > New > Other. Select Designer on the left side of the page and JFace Dialog on the right side. Click Next to go to the next page. On the next page enter in the class name for your new dialog and then click Finish. You should now see the following in the Content Pane: The area between the title bar and the buttons is called the dialog area and the area where the buttons are is called the button bar. Any normal SWT controls can be added to the dialog area. Below is shown a label and a text field added to the dialog area An Eclipse GUI Builder University of Manitoba 42

257 The buttons in the button bar are not normal buttons. They are special JFace dialog buttons. Only JFace dialog buttons can be added to the button bar. You can create buttons in the button bar by selecting Dialog button from the JFace category in the Control Palette and then placing the button on the button bar. You can change the button type in the type property in the Inspector. The text of the button is automatically changed to reflect the type. Shown below is a Retry button added to the button bar. You can change the text on a button using the text property in the Inspector. Below, the Retry button s text is changed to Clear. You can change the title of a dialog by selecting the dialog and then changing the title property in the Inspector. If we look at the source code now, we see that the controls in the dialog area are declared in the createdialogarea() method, the buttons in the button bar are declared in the createbuttonsforbuttonbar() method, and the dialog s size and title are set in the configureshell() method. The abstract class, Dialog, which our dialog class extends, implements the methods buttonpressed(), okpressed(), and cancelpressed(). The buttonpressed() method gets called anytime a button is pressed and the ID of the button is passed as a parameter. The okpressed() method is called every time the OK button is pressed and the cancelpressed() method is called every time the Cancel button is pressed. If you want to perform an action in the dialog when one of the dialog buttons is pressed, you would override one of the methods above. If we want to make our Clear button clear the text field we have to override the buttonpressed() method. Our buttonpressed() method is shown below. protected void buttonpressed(int buttonid) { if (buttonid == IDialogConstants.RETRY_ID) text.settext(""); super.buttonpressed(buttonid); 12 - An Eclipse GUI Builder University of Manitoba 43

258 Since our Clear button is really a Retry button, we check if the Retry button has been pressed. If it has, the text field is cleared. Because the superclass, Dialog, already handles presses to the OK and Cancel buttons properly, we can simply call its buttonpressed() method. If you want to explicitly set the return code of the dialog, you can call the setreturncode() method, passing an integer representing the button ID as a parameter. To open our dialog, we need to create an instance of it from another class and then call its open() method. Inside an SWT application, create an instance of our dialog class, passing the Shell of the application to the constructor of the dialog. You can then call the dialog s open() method whenever you want to open the dialog. The open() method returns an integer representing the return code of the dialog. You can also get the return code of the dialog by calling the dialog s getreturncode() method. You can use this return code to determine which button was pressed. JFace Wizard Page Creation (Professional Version Only): Wizards are a very useful form of user input. They are used when multiple steps are needed to be completed by the user. JFace allows you to quickly and easily set up a wizard user interface. To create a JFace wizard, you need three types of objects. First you will need a container to hold the wizard. For a stand-alone application you would use a WizardDialog object. Then you need a wizard object that extends the Wizard class and finally a number of separate wizard pages, each extending the WizardPage class. To learn how to fully create a JFace wizard, see the JFace Wizards tutorial at The SWT Designer allows you to create the content for each individual wizard page. To create a wizard page select File > New > Other. Select Designer on the left side of the page and JFace Wizard Page on the right side and then click Next. On the next page enter in the class name for your new wizard page and then click Finish. You should now see the following in the Content Pane An Eclipse GUI Builder University of Manitoba 44

259 The wizard page s title bar and button bar is the same for all wizard pages in a wizard so you are unable to modify them in the SWT Designer. If you select the entire wizard page, three properties are displayed in the Inspector. All three properties change the top section of the wizard page. The description property allows you to change the page s description, the imagedescriptor property allows you to set an image to the top-right corner of the page, and the title property allows you to change the page s title. There is a container in the center of the wizard page in which you are able to add controls. This is the unique part of each wizard page. You can add regular SWT controls just like you would when designing a regular SWT Application. It is easy to create a wizard page like the ones in the tutorial from the above link. Shown below is the wizard page, HolidayMainPage, which was created using the SWT Designer. If you look at the source code generated by the SWT Designer, you will see that all of the code for the controls that you placed in the container are in the method createcontrol() and the code for the top section including the wizard page title and description are in the wizard page s constructor. After you have created all your wizard pages, you can put them together and add functionality to them. To learn how to do this, look at the tutorial on JFace Wizards by following the link given above An Eclipse GUI Builder University of Manitoba 45

260 JFace Application Creation (Professional Version Only): A JFace application is very similar to an SWT application. Both allow you to place SWT controls on the shell, both allow you to have a menu, and both allow you to have a toolbar. However, creating menus and toolbars for a JFace application is quite different than creating menus and toolbars for an SWT application. A JFace application also gives you the option of having a status bar at the bottom of your window. To create a JFace application, select File > New > Other. Select Designer on the left side of the page and JFace ApplicationWindow on the right side and then click Next. Type in the desired name for your class and click Finish. The Content Pane should now display what looks like a shell for a normal SWT application. The Control Tree, Method List, and the Inspector, however, contain different items for a JFace application than for an SWT application. The Control Tree s root is an item called (application window). It is the equivalent of the shell in an SWT application except you cannot place controls directly on it. The (application window) item has two children, composite and (actions). You place your controls on the composite which covers the entire area of window. The (actions) item has children which are all the actions for the application. We will look at what actions are further down. The Method List shows us that all the controls are created in the createcontents() method. When the (application window) item is selected, the Inspector only shows the properties size and title. The title property allows you to change the text that is displayed on the title bar of the application window and the size property allows you to change the size of the window. If you look at the source code of your JFace application, you will see that several methods have been created. The more noteworthy ones are createcontents(), createactions(), createmenumanager(), createtoolbarmanager(), configureshell(), and run() An Eclipse GUI Builder University of Manitoba 46

261 The createcontents() method is where all of the controls are created. The createactions(), createmenumanager(), and createtoolbarmanager() methods are where the actions, menus, and toolbar are created. The configureshell() method is where the window size and the text in the title bar is set. The run() method opens up the application window. It calls the open() method, retrieves the display and shell, and starts the event loop. You can place controls on the window the same way you place controls on an SWT window. The only difference is that you are placing the controls on a composite instead of directly onto the shell. Placing a menu or a toolbar in an SWT application requires you to add menu and toolbar controls to your shell. The items in your menus and toolbars are independent of each other. If you want to have the same function on both a menu and a toolbar, you have to create two separate items with two separate event handlers. In a JFace application, you combine these separate items that have the same function into one item called an action. An action is a command that is activated by the user when either a menu item or a toolbar item is selected. It allows the same behavior to be used by both a menu item and a toolbar item, reducing redundant code. For example, in Eclipse you can save a file by either selecting Save from the File menu or by clicking on the Save button in the toolbar. Selecting either of these items will execute the same action. While editing a JFace application in the SWT Designer, you may notice two tabs just above the Control Palette named Content and Actions. Clicking on the Actions tab will turn the Control Palette and the Content Pane into the Actions Pane. Clicking on the Content tab will return you to the Control Palette and the Content Pane. If you click on the Actions tab, you should see the Actions Pane shown below An Eclipse GUI Builder University of Manitoba 47

262 The Actions Pane is split up into three sections: Actions, Toolbar, and Menu. All three sections have a couple of buttons at the top with a tree below. There are already several items in the actions tree. Listed under (contributions) are two items, a separator and a menu manager. The separator can be dragged to the toolbar and menu trees. This creates a visible separator between items in the toolbar and menu. You can place as many separators as you want. The menu manager can only be dragged to the menu tree. Each menu manager is a submenu of the menu it was placed in. You can place as many menu managers as you want. Listed under (actions) in the actions tree are all the created actions. You can add and remove actions by clicking on the plus (+) and minus (-) buttons above the actions tree. Below is shown several actions added. If you select an action, the following is displayed in the Inspector: 12 - An Eclipse GUI Builder University of Manitoba 48

263 You can set the image for the action that is displayed in the toolbar and menu with the imagedescriptor property. You can also set the disabledimagedescriptor and hoverimagedescriptor properties if you want separate images to be displayed when the action is disabled or when the mouse is moved over the toolbar item. The text property sets the text beside the menu item. The & character in front of a letter indicates that the letter is a mnemonic. Anything after character is the accelerator key. The tooltiptext property sets the tool tip that will be displayed if you move your mouse over a toolbar item. To add actions to the toolbar or a menu, simply click on the action in the actions tree and drag it to the desired position in the toolbar or menu tree. Below, several actions have been added to the toolbar and menu. To change the placement of actions, simply drag them to their desired position. In the toolbar section you can also use the up and down buttons above the toolbar tree. To remove actions from the trees, select an action and press the minus (-) button above the tree. Double-clicking an action in the actions tree will switch to the source view with your cursor in the action s run() method. The run() method is where you place the eventhandling code. An action s run() method is executed every time it is selected from either the menu or the toolbar in a running program. Shown below are the effects of adding actions to the menu and the toolbar An Eclipse GUI Builder University of Manitoba 49

264 Whether you select the Save item from the menu or the Save item from the toolbar, the same run() method will execute since both items are linked to the same action. For more information on creating JFace applications, see the JFace tutorial. Code Generation Options: The Designer supports generating code in numerous ways. Some code generation settings that you can modify are the style of code that is generated, the default variable names of controls, and where variables for controls are declared. To modify the code generation settings, select Preferences from the Windows menu, expand the Designer item and then select Code Generation. The Code Generation preference page for the professional version of the Designer is shown below. The free version of the Designer only includes the Use the existing block style when it can be deduced and Create every component in its own block settings An Eclipse GUI Builder University of Manitoba 50

265 When Create every component in its own block is selected, the Designer generates code using the block style: a control is declared and instantiated inside its own block of code. All of the control s properties are placed in the block. The block is surrounded by opening and closing braces. Child controls are nested in their parent s blocks. When a control is declared inside its block of code, it is visible only to its children and itself. A control can be made visible to the rest of the class using the Convert local to field button. In the examples at the end of this tutorial we will see the block style in more detail. Below is a simple example of what the block style looks like. { final Button button = new Button(shell, SWT.NONE); button.settext("button"); When Create every component in its own block is not selected, the Designer generates code using the flat style: all controls are created in the same scope in a method making the controls visible anywhere in a method after they have been declared. When Use the existing block style when it can be deduced is selected, the Designer attempts to use the existing code style already in a file to generate code. The Designer checks a file when it is opened in the editor to see if one style or the other is used. If only one of the styles is being used in a file, it will continue generating code in that style, regardless of what the Create every component in its own block setting is set to. If no style is detected (no controls have been created yet) or if more than one style is detected, the Designer will generate code as set in the Create every component in its own block setting. When Create every component as a field by default is selected, all created controls are automatically created as a field in the class. When Prefix component creation code by is selected, the text field below it is enabled. If the text field is left blank, every new control created will have a blank line above it in the source code. You can also place a custom one-line comment before each new control by putting the comment in the text field. The text field must be blank, start with //, or start with /* and end with */. If the text field is not blank and does not hold a comment, new controls will not be created. By selecting one of the radio buttons under Create variable declarations, the Designer will place declarations of variables either on the same line as where they are first assigned a value or at the top of the method. The Make declarations final setting makes all declarations final by placing the final keyword before each declaration. The Share variables if possible setting makes the Designer reuse variable names like griddata, formdata, label, button, etc. The Make declarations final and Share variables if possible settings cannot both be selected at the same time An Eclipse GUI Builder University of Manitoba 51

266 When Create stub event handler methods named is selected, the text field below it is enabled. Now whenever an event handler is added, a method stub is created with the name given in the text field. A line of code is also added to the event handler which calls the newly created method. If you move your mouse over the text field, a tool tip will appear which gives you information on how to specify the names of the method stubs generated. Type Specific Code Generation Options (Professional Version Only): If you expand the Code Generation item and select the Type Specific item in the Preferences window, the Type Specific Code Generation preference page is shown. In this page you can set code generation settings for individual types. There are already several types listed in the table. You can add more types by clicking on the Add button and entering in the name of the class you want to add in the dialog box that appears. To remove a type, highlight it in the table and click on Remove. The Default Name column of the table lets you change what variable name is initially used when a control of that type is created. To change the default name, simply click in the table cell that you wish to modify and type in the name. Press Enter to apply the change or Esc to cancel. The As Field column has a checkbox for each table item. If an item s As Field cell is checked, all new controls of that type will be created as a field. When a control is created as a field, it places the declaration of the control in the class outside of any methods An Eclipse GUI Builder University of Manitoba 52

267 Additional Features of the Designer: There is a quick way to edit the text property of buttons (including check and radio buttons), labels, text fields, groups, and table columns. First select a control in either the Content Pane or the Control Tree. Hold down the Alt key and then click on the control in the Content Pane. An edit box will appear in which you can set the control s text property. To use this feature, you must enable the Allow direct edit preference. To enable it, select Window > Preferences. On the left side of the Preferences window, expand Designer and click on General. Make sure that Allow direct edit is checked on the right pane of the window and click OK. The Designer allows you to cut, copy, and paste controls. To cut or copy a control, simply select a control and select cut or copy from the toolbar above the Content Pane or from the Edit menu. Alternatively, you can also right-click on a control in either the Content Pane or the Control Tree and select cut or copy from the resulting menu. To paste a control, select paste from the toolbar above the Content Pane, from the Edit menu, from the Control Palette, or from the right-click menu of the Content Pane or the Control Tree, and then place the control in the desired position in either the Content Pane or in the Control Tree. The control that was pasted will then have most of the same properties as the original control. The events and the variable name properties are not copied. The Designer includes a very handy feature allowing you to view how your Application will look without compiling and running the entire application. There are a couple of ways to run this test. The first is to click on the Test button on the toolbar above the Content Pane. There is also a Test button on the main Eclipse toolbar when a file is open in the Designer editor. The other way is to right-click anywhere in the Content Pane or in the Control Tree and select Test from the popup menu. Running the test will bring up a window of your application. None of your own code will run, just the code that is generated by the Designer. The main purpose of the test is to see what the controls look like together, and you can test what happens when you resize and move the application window. You can close the test window by click on the X in the top-right corner of the window or by clicking a mouse button on a blank area of the shell. If your shell window is larger than your content pane, you cannot see the whole shell at once. To allow you to see a small version of what the whole shell looks, the Designer has a thumbnail view. To enable this view, select Window > Preferences, expand Designer and select General. In the preference page on the right select Show thumbnail in Outline view. Now a thumbnail view of your shell is visible in the Outline view (you will have to close and reopen any currently open files to see this). If your shell is larger than your content pane, a gray box appears outlining which part of the shell is currently visible. You can click and drag the box around to display different areas An Eclipse GUI Builder University of Manitoba 53

268 A number of controls, such as buttons, shells and menu items have an image property. Setting this property is the same for all the controls with this property. To set this property, select the control, click on the image property in the Inspector, click on the button that appears in the property editor, and choose an image from the list of images in the window that appears. There are two options in the Select Image window. If the Relative to class option is selected, only images that are in the same package or a subfolder of the package that the class is in are shown. If the Relative to project option is selected, images in the project folder or any of the project s subfolders are shown. A shell has several style properties that can be set. To change a shell s style, select the shell and expand the style property in the Inspector. By changing the style properties such as border, min, and resize, you can change the look of the shell. The trim property has several options. When default is selected and all the other style settings are their defaults, a regular shell is displayed. If any of the other style properties are set to true when the trim property is set to default, only the style properties set to true are set. The shell_trim value is the same as setting close, title, min, max, and resize to true. The dialog_trim value is the same as setting title, close, and border to true. With the no_trim value set, none of the other styles will be able to be shown except title. If you want to create several controls of the same type at once, it can be cumbersome to select the control from the Control Palette each time. If you hold down Ctrl as you are selecting a control from the Control Palette, you can place several controls at once. You can keep clicking on the Content Pane and new controls will be added. To stop adding controls of that type, either click on an open spot in the Control Tree or select another control from the Content Pane. The Designer fully supports multiple level undo and redo. If you wish to undo or redo an operation performed by the Designer such as accidentally deleting a control, you can just choose undo or redo from the Edit menu of Eclipse. Since the Designer supports multiple levels of undo and redo, you can undo and redo multiple operations. The z-order is a hierarchy of controls. It affects some things in SWT such as which controls can be attached to other controls in the FormLayout, the tab order of the controls, and the location of a control on the FillLayout, RowLayout, and GridLayout. The z-order is shown in the Control Tree and in the source code. A control that is higher up in the Control Tree is higher up in the z-order. There are a few ways to modify the z- order in the Designer. The easiest way is to drag the controls around in the Control Tree. If the FillLayout, RowLayout, or GridLayout is used, you can also drag the controls around on the Content Pane to modify the z-order. You can also manually move the blocks of code around in the source code, but this is not recommended because there are easier ways to modify the z-order. When the z-order is modified, the changes are reflected in the Control Tree, the Content Pane, as well as the source code An Eclipse GUI Builder University of Manitoba 54

269 In the professional version of the Designer, you can modify properties on multiple controls at once. There are several ways to select multiple controls in the Designer. If you hold down Ctrl, you can click on multiple controls in the Control Tree or the Content Pane. In the Content Pane, you can hold down Shift to select individual controls. If a control is selected and you hold down Shift and then click on a control in the Control Tree, all the controls between the two controls in the Control Tree will be selected, inclusively. You can also use the Marquee tool, which is at the top of the Control Palette to select multiple controls. When the Marquee tool is selected, the cursor will turn into crosshairs and you can click and drag a box around multiple controls on the Content Pane to select them. To return to the regular cursor, just click on the Select tool at the top of the Control Palette. When multiple controls are selected, all of their shared properties are listed in the Inspector. If not all the selected controls have the same value for a property, the property editor in the Inspector will be blank. You can also move and resize multiple controls when using the NullLayout or FormLayout. Creating a UI: Two Examples We are going to go through a couple of examples to demonstrate how to create a GUI using the Designer. In the first example we will create a GUI for a simple Address Book application. We will be designing the first example in SWT only using features from the free version of the Designer. We will also create a GUI that is equivalent to an already existing GUI for a Client Billing Application from a previous tutorial. We will be designing the second example in both SWT and Swing, using the professional version of the Designer. It will be beneficial to go over both examples regardless of whether you are using the free or professional version of the Designer. If you are going over the second example while using the free version, you may have to use some slightly different methods to achieve the same results, but they are not hard to do. Creating a GUI for an Address Book Application: We are going to go through an example of how to create a GUI for an Address Book application. Because this example only shows how to build a GUI, the example application will have no real functionality. Creating a new Project: Select File > New > Project, and then select Designer > SWT/JFace Java Project. Set the project name to AddressBook. Creating a new SWT Application: Select File > New > Other, then click on Designer > SWT Application and hit Next. Set the name to AddressBookUI, select the public open() method radio button under Create contents in: and then click Finish An Eclipse GUI Builder University of Manitoba 55

270 Your generated class source code should look like the following: public class AddressBookUI { public static void main(string[] args) { AddressBookUI window = new AddressBookUI(); window.open(); public void open() { final Display display = new Display(); final Shell shell = new Shell(); shell.settext("swt Application"); shell.open(); while (!shell.isdisposed()) { if (!display.readanddispatch()) display.sleep(); As you can see above, the Designer creates two methods. The open() method contains all your GUI code, and your main() method calls the open() method. In a real application, you may have several classes, and you may want to have your main() method in another class. We will leave it in this class in order to make it easy to run our GUI. The Designer automatically creates instances of Display and Shell. It sets the name displayed in the title bar of the shell and then opens the shell. The Designer also creates an event loop. Since the Designer initially generates all the code needed to create a window, we can run the application and see a blank window. While the AddressBookUI.java file is in focus in the editor, select Run > Run As > Java Application. A blank window should appear. Close it by clicking on the X on the top-right corner. Designing the GUI Window: Expand the editor window by double-clicking on the tab above the editor that shows AddressBookUI.java. Click on the design tab on the bottom of the screen to enter the Designer s design view An Eclipse GUI Builder University of Manitoba 56

271 We will be using a NullLayout for the shell, so make sure that you have enabled it by following the instructions that can be found in the NullLayout section of this tutorial. In a real application, it would be best to use layout managers in order to make the application more portable, but for this simple example a NullLayout will be sufficient. First, we will change the title from SWT Application to Address Book. Select shell in the Control Tree and change the text property in the Inspector to Address Book. Next we will create the buttons on the bottom of the window. Select the Button control from the Control Palette. Now on the bottom left corner of the window in the Content Pane, draw out a button. In the Inspector, set the text property to be New and set the variable property to be newbutton. Your window in the Content Pane should look something like the following: Now we create two more buttons called deletebutton and editbutton with the text as Delete and Edit, respectively. Now make sure that a button is selected. Click on the Open definition button. You should see the following lines added to your code: { { { final Button newbutton = new Button(shell, SWT.NONE); newbutton.setbounds(10, 380, 75, 35); newbutton.settext("new"); final Button deletebutton = new Button(shell, SWT.NONE); deletebutton.setbounds(85, 380, 75, 35); deletebutton.settext("delete"); final Button editbutton = new Button(shell, SWT.NONE); editbutton.setbounds(160, 380, 75, 35); editbutton.settext("edit"); 12 - An Eclipse GUI Builder University of Manitoba 57

272 You should notice the opening and closing braces on the top and the bottom of the code for each button. Within these braces is a block of code that creates and configures the button. Go back to the design view and select the New button. Then click on the Convert local to field button. The Convert local to field button s image changes and its tooltip changes to Convert field to local. Switch back to the source view and we will see what occurred by clicking on this button. Look at the top of the class, just before the main() method. You should see a new line added: private Button newbutton; Also, final Button is removed from the beginning of the button instantiation in its block. Declaring the button outside the block and as a field in the AddressBookUI class allows you see and modify its properties anywhere in the AddressBookUI class. All that you have to do to convert a control to a field of the class is to click on the Convert local to field button. To change the control back to local, just click the button again. Now convert the other two buttons into fields by clicking the Convert local to field button for each of them. We will now finish creating the other buttons. Name these buttons prevbutton, nextbutton, savebutton, and cancelbutton. Set their text to be Previous, Next, Save, and Cancel, respectively. To quickly set the text on the buttons, select the button, hold down Alt and click on the button in the Content Pane. Make sure you enable the Allow Direct Edit setting in the Designer s properties. Your window should now look something like this: Now create a group in the top part of the shell by selecting Group from the Control Palette, click and hold down the mouse button on the top-left corner of the shell, and then drag the group across the rest of the shell. Set the text of the group to Details An Eclipse GUI Builder University of Manitoba 58

273 We now create a label and a text field inside our newly created group. Make sure that the label and the text field are children of group in the Control Tree. If they are, they will be listed under the group and indented a little bit. Set the label s text to First Name: and the text s variable name to fnametext. Because we will never have to set properties of the label in our code, we will just leave the label as local and keep label s variable name as label. Select fnametext and click on the Convert local to field button. Your window should now look something like this: Click on group in the Control tree and then click on the Open definition button. You should see the following code added to your class: { final Group group = new Group(shell, SWT.NONE); group.settext("details"); group.setbounds(10, 10, 585, 355); { final Label label = new Label(group, SWT.NONE); label.setbounds(10, 20, 135, 25); label.settext("first Name:"); { fnametext = new Text(group, SWT.BORDER); fnametext.setbounds(150, 15, 420, 25); 12 - An Eclipse GUI Builder University of Manitoba 59

274 You can see that the group is in a block just like the buttons are. You may notice that the label and the text field are both nested in the group block. This is because they are both children of group. The Designer nests all control blocks inside their parent container s block. The declaration for fnametext is higher up in the source code with the other field declarations. Now return to the design view. Create five more labels and five more text fields. Set the text in the labels to Last Name:, Phone:, , Address:, and Miscellaneous Information. Set the variable names of the text fields to lnametext, phonetext, text, addrtext, and misctext. Under the style complex property of both addrtext and misctext, set the v_scroll property to true. This adds vertical scrollbars to the text fields. For all the text fields, make sure that each is a field by clicking on the Convert local to field button. Now your window should look something like this: Use the Designer s test feature to see what your window will actually look like by clicking on the Test toolbar button. Close the window by clicking on the X in the topright corner of the window. Save and run the application. The window we get when we run the application is probably a different size than the window we got when we used the Designer s test feature. To make the window the size that we specify, right-click on the shell in the Control Tree or Content Pane, and then select Set shell size > Using the setsize() method. Now make sure you resize the shell window on the Content Pane to the desired size. Select the shell and then click on Open definition. You should see a line similar to the following added: shell.setsize(610, 477); Now try compiling and running your application again. You will notice that your application is now the same size as the shell in the Content Pane An Eclipse GUI Builder University of Manitoba 60

275 Note: The Designer will add all the appropriate imports into your code that are necessary for your GUI to work. These are the imports that the Designer has put into our application so far: import org.eclipse.swt.widgets.display; import org.eclipse.swt.widgets.shell; import org.eclipse.swt.swt; import org.eclipse.swt.widgets.button; import org.eclipse.swt.widgets.group; import org.eclipse.swt.widgets.label; import org.eclipse.swt.widgets.text; Creating Menus: Though the professional version of the Designer supports building menus, the free version does not. If we wish to design a menu using the free version of the Designer, we will have to code it ourselves. In order to create the menu, we will create a method in AddressBookUI called setupmenu(). Since we create the menu on the shell, shell will have to be visible to this method. In the design view, select shell from the Control Tree and click on Convert local to field. The remainder of the creation of the menu will be done in the source view. Add the following line to your list of imports: import org.eclipse.swt.widgets.*; Then add the following method to your AddressBookUI class: private void setupmenu() { //create the menu bar Menu menu = new Menu(shell, SWT.BAR); shell.setmenubar(menu); //add the File option to it MenuItem file = new MenuItem(menu, SWT.CASCADE); file.settext("file"); //create a menu for the File option Menu filemenu = new Menu(file); file.setmenu(filemenu); //add MenuItems to the File menu MenuItem previtem = new MenuItem(filemenu, SWT.NONE); previtem.settext("previous"); MenuItem nextitem = new MenuItem(filemenu, SWT.PUSH); nextitem.settext("next"); MenuItem seperator = new MenuItem(filemenu, SWT.SEPARATOR); MenuItem quititem = new MenuItem(filemenu, SWT.PUSH); quititem.settext("quit"); //add listeners for the actions previtem.addlistener(swt.selection, new Listener() { public void handleevent(event e) { System.out.println("Previous menu item selected."); ); 12 - An Eclipse GUI Builder University of Manitoba 61

276 nextitem.addlistener(swt.selection, new Listener() { public void handleevent(event e) { System.out.println("Next menu item selected."); ); quititem.addlistener(swt.selection, new Listener() { public void handleevent(event e) { shell.dispose(); ); Here, as you can see, we do not use the block style. All controls declared in this method are visible throughout the entire method. This style of coding is called flat style. Now, just before the shell.open() call in your open() method, place a call to the new setupmenu() method. setupmenu(); shell.open(); while (!shell.isdisposed()) { if (!display.readanddispatch()) display.sleep(); If you return to the design view, you will see the menu on the Content Pane. You can click on the individual menu components and change some of their settings, but you cannot create new menu items. Because the menu takes up some space on the shell, the buttons on the bottom of the shell may have part of their bottoms cut off as shown below. Simply resize the shell to fix this. Now try compiling and running your application. Make sure you can see the console on the bottom of your screen. Then try selecting Previous and Next from the File menu. Messages should be sent to the console when you select one of the menu items. Quit will close the application. For more information on creating menus, see the tutorial Advanced SWT Widgets An Eclipse GUI Builder University of Manitoba 62

277 Creating Event Handlers: We are now almost done creating our GUI. All that is left to do is to create some functionality. This primarily involves setting up event handlers for the buttons. The Designer will set up the proper framework for the event handlers, but we will have to code what we want the application to do when an event is triggered. We will now go over what sort of actions and events we want to take place in our application. First, we want all the text fields to initially be non-editable. They will only be editable if we select either the New or the Edit button. The Save and Cancel buttons will initially be disabled. If the New button is selected, all the text fields will be cleared and made editable, the New, Delete, and Edit buttons will be disabled, and the Save and Cancel buttons will be enabled. The same will happen with the Edit button, except the text fields will not be cleared. While editing, if either the Save or the Cancel button is selected, the text fields will return to being non-editable, the New, Delete, and Edit buttons will be re-enabled, and the Save and Cancel buttons will be disabled. If the Delete button is selected, all the text fields will be cleared of their text. For all the buttons, a message will appear in the console saying which button was pressed. First of all we will set up the initial window state. To initially make the text fields be non-editable, you can set their style to be read only. Select each text field and under the style complex property in the Inspector, set the read_only property to true. Disabling the Save and Cancel buttons is also easy. Select each button, and then in the Inspector, set the enabled property to false. Instead of placing all the lines of code that modify the properties of the controls inside the event handlers, we will create methods for each action. This is because an action may take place on several different occasions. This also makes our code more readable. We will create four new methods called cleartext(), settexteditable(), enableeditbuttons(), and enablesavebuttons(). They are as follows: private void cleartext() { fnametext.settext(""); lnametext.settext(""); phonetext.settext(""); text.settext(""); addrtext.settext(""); misctext.settext(""); 12 - An Eclipse GUI Builder University of Manitoba 63

278 private void settexteditable(boolean editable) { fnametext.seteditable(editable); lnametext.seteditable(editable); phonetext.seteditable(editable); text.seteditable(editable); addrtext.seteditable(editable); misctext.seteditable(editable); private void enableeditbuttons(boolean enable) { newbutton.setenabled(enable); deletebutton.setenabled(enable); editbutton.setenabled(enable); private void enablesavebuttons(boolean enable) { savebutton.setenabled(enable); cancelbutton.setenabled(enable); Now double-click the New button. The view should be switched to your source code and a stub for an event handler should have been created. Make your code look like this: { newbutton = new Button(shell, SWT.NONE); newbutton.addselectionlistener(new SelectionAdapter() { public void widgetselected(selectionevent e) { cleartext(); settexteditable(true); enableeditbuttons(false); enablesavebuttons(true); System.out.println("New button selected."); ); newbutton.setbounds(10, 380, 75, 35); newbutton.settext("new"); You can see that when the New button is clicked, the text fields are cleared and made editable, the edit buttons (New, Delete, Edit) are disabled, the save buttons (Save, Cancel) are enabled, and a message is sent to the console saying that the New button was selected. In the same way, add the following code to each of the buttons. Delete button: cleartext(); System.out.println("Delete button selected."); Edit button: settexteditable(true); enableeditbuttons(false); enablesavebuttons(true); System.out.println("Edit button selected."); Previous button: System.out.println("Previous button selected."); Next button: System.out.println("Next button selected."); 12 - An Eclipse GUI Builder University of Manitoba 64

279 Save button: settexteditable(false); enableeditbuttons(true); enablesavebuttons(false); System.out.println("Save button selected."); Cancel button: settexteditable(false); enableeditbuttons(true); enablesavebuttons(false); System.out.println("Cancel button selected."); Run the application. Play around with it a little bit to see what happens because of the code that you added to your buttons. Look at the console to view the messages that are printed when the buttons are clicked. We have now finished creating the GUI for a simple Address Book application. Though this application has no real practical use in its current form, a database could be added to make the application a fully functional address book. For information on how you would add functionality to a GUI by adding a database, see the tutorials Client Billing Application and Time-Tracker Application. For more information on events and event-handling, see the tutorials Basic SWT Widgets and Advanced SWT Widgets. Creating an SWT GUI for a Client Billing Application: In order to help you learn the Designer better and to see some differences between the free and professional versions of the Designer, we will look at a Client Billing application that is taken from the Client Billing Application tutorial. We will create an equivalent GUI using the Designer. In this example we will be using the professional version of the Designer. You can still go through this example if you are using the free version of the Designer; however, you will have to use alternate means for some operations such as when we are designing using the FormLayout and when we design menus. Note: This example is quite a bit more advanced than the previous example. Before going through this example it is suggested that you understand the various controls and layouts by looking at the Basic SWT Widgets, Advanced SWT Widgets, and Eclipse Layouts tutorials. You should also look at the Client Billing Application tutorial to better understand how the rest of the application fits together with the GUI. If you do not already have the example source code for the Client Billing Application tutorial, get it now from An Eclipse GUI Builder University of Manitoba 65

280 Taking a Look at the Original GUI: The source code for the GUI of the Client Billing Application is all in ClientBillingUI.java. The main() method is in ClientBilling.java. Open up ClientBilling.java and select Run > Run As > Java Application. The application should look like the following: 12 - An Eclipse GUI Builder University of Manitoba 66

281 You may notice that the Clients group on the left is in both tabs and does not change. If you look at the source code, the group is created directly on the TabFolder, and not on the TabItems. This is not considered to be a standard practice and because of that the Designer does not support this. For the GUI that we will create in this tutorial we will place the Clients group outside of the TabFolder. In this tutorial we will not fully integrate the GUI with the rest of the application, but in order to easily do so in the future, we will use the same variable names as the original GUI. You may wish to take a look over the ClientBillingUI class to understand how it works. Creating Our Own ClientBillingUI: Now we are ready to create our own GUI for this application. If you are adding to the existing ClientBilling project, be sure to add jface.jar to the project build path. Create a new SWT Application. Name the class ClientBillingUIDesigner and select the option to create the contents in the open() method. After the class has been created, switch to the design view. In the Inspector, set the text property for shell to Client Billing Application. Click in the editor of the image property in the Inspector and then click on the button that appears. Set the radio button on the top of the window to Relative to Project. Select splash.jpg from the list of images and click OK. The icon on the top-left corner of the window now displays the image. Set the shell s layout to FormLayout. If you are using the free version of the Designer, you are still able to use FormLayout. Since you cannot place a FormLayout using the free version, you must set the layout of a container to FormLayout by hand. To do this, use the setlayout() method of the container to set the layout to FormLayout right after the instantiation of the container. For example, if you wish to set the shell s layout to FormLayout, add the line shell.setlayout(new FormLayout()); right after the line final Shell shell = new Shell(); Then switch back to the design view to add controls to the shell. To change control s layout properties using the free version of the Designer, you will have to change them in the Inspector An Eclipse GUI Builder University of Manitoba 67

282 Creating the Client List Group: Now we will create the group that contains the list. Add a group to the shell. Place your mouse in the top-left quadrant of the group so that the thick lines appear on the top-left corner of the group. Move the group to the top-left corner until the two blue margin lines appear. Drop it so that the top-left corner is close to the top-left corner of the shell. This creates snap points on the shell s margins. Now drag the bottom of the group to the bottom of the shell and snap it to the bottom margin. While the group is selected, click on the small button on the right side of the group. Click on the button with the percent symbol (%). Now drag the right handle of the group to 25%. The tool tip just below the shell tells you what percent you are at while you are dragging it. Set the group s text to Clients. Set the group s layout to GridLayout with two columns. Since a container inherits its parent s layout, you will have to delete the FormLayout first. Simply click on the layout property in the Inspector and press Delete. Add a list, a label, a text field, and two radio buttons. Name the list clientlist, convert it to a field, and set the horizontal span to 2. Set the label s text to Filter:. The text field should be named filtertext. The two radio buttons should be named nameradio and numradio, and their text should be View by Name and View by ID, respectively. Set the horizontal span for both radio buttons to 2. Set the list to fill horizontally and vertically and to grab horizontally and vertically. Set the text field to fill horizontally. Test your design by clicking on the Test button on the toolbar. Your shell should look something like this: When layouts are used, resizing a window will also resize the controls inside of it. This allows the controls to be properly visible even at different window sizes as shown below An Eclipse GUI Builder University of Manitoba 68

283 Creating a Tabbed Folder: Now create a TabFolder on the shell to the right of the group. Attach the top, right and bottom sides of the TabFolder to the margins like you did with the group. Drag the left side right beside the Clients group until a blue line appears. Now the TabFolder is snapped to the right side of the group. Again, test your shell to see the effects of the layout settings. Now place two TabItems on the TabFolder. Set the text on them to be Clients and Transactions. To switch between the tabs in the SWT Designer, simply click on the tab you wish to switch to. Your shell should now look like this: A TabItem only allows one control to be placed directly on it. If you want to place more than one control on a TabItem, you should use either a composite or a group as the one control. Then you can place more controls on that group or composite. For this application we will place a group on both TabItems. The Clients Tab: The group in the Clients tab should be named clientinfo and should be converted to a field using the Convert local to field button. Set the group s layout to FormLayout. The group will hold the labels and the text fields and a composite. The composite will hold the row of buttons at the bottom and should have a horizontal FillLayout An Eclipse GUI Builder University of Manitoba 69

284 Create eight text fields and name them acctidtext, fnametext, snametext, dobtext, phonetext, text, addresstext, and miscinfotext. Use the convert local to field button to convert all of the text fields to fields. The top text field should be snapped to the top and right margins of the group. The other text fields should have their top side snapped to the bottom of the text field above it and their right side to the right margin of the group. Drag the left side of acctidtext a bit to the left so that it is longer than the other text fields. Now drag the left side of all the other text fields to the left and snap them to the left side of acctidtext. Now when acctidtext resizes, the rest will too. Set the read_only style property to true for each text field. Set the v_scroll style property to true for addresstext and miscinfotext. Create eight labels on the group and set their text to Account ID:, First Name:, Surname:, Date of Birth:, Phone Number:, Address:, Address:, and Miscellaneous Information:. Snap the top of each label to its corresponding text field, and snap the left side of each label to the left margin of the group. You can tell when you are attaching to a margin because a blue line appears. Drag the left side of acctidtext so that it is a little bit to the right of the longest label. Make sure that the snap point button for the left side of acctidtext is a number sign (#) with an arrow pointing left. Your shell should now look something like the following: Add a composite to the group. Set the left, bottom, and right side attachments to the group margins. Click on the button for the top attachment and click on the button with the number sign (#) and a down arrow. Drag the top side till the number in the tool tip to the right of the composite shows approximately An Eclipse GUI Builder University of Manitoba 70

285 Set the layout on the composite to FillLayout. On the composite, create three buttons, one label, two more buttons, another label, and then another button. The labels are to create space between the buttons. Remove the text in each label. Name the buttons newclientbutton, delclientbutton, editclientbutton, saveclientbutton, cancelclientbutton, and printtransbutton. Set their text to New, Delete, Edit, Save, Cancel, and Print, respectively. Use the convert local to field button to make the buttons visible in the class. Set the enabled property of saveclientbutton and cancelclientbutton to false. Your shell should now look like this: The Transactions Tab: To modify the Transactions TabItem, click on the tab in the Content Pane. Add a group to the TabItem and name it transinfo. Convert the group to a field and set its layout to GridLayout with one column. Create a table and two composites in this group. The first composite contains the labels and text fields. Set its layout to GridLayout with four columns. The second composite holds the buttons and its layout should be a horizontal FillLayout. Set the horizontal fill property for both composites to true. Name the table infotable. Set the full_selection property of the table to true. Set the horizontal and vertical grab and fill properties of the table to true. Add four table columns and name them numbercolumn, amountcolumn, datecolumn, and desccolumn. Set their text to ID, Amount, Date, and Description, respectively. Convert the table and all four columns to fields by using the convert local to field button. Set the align property of amountcolumn and datecolumn to right. If the columns do not all fit, shorten the length of the first three columns An Eclipse GUI Builder University of Manitoba 71

286 On the first composite, place five labels and five text fields with the labels and text fields alternating. Set the labels texts to be Total:, ID:, Description:, Amount:, and Date. Name the text fields totaltext, idtext, desctext, amttext, and datetext. Set all the text fields to read_only and convert them all to fields. Set the wrap property of desctext to true. Set the horizontal span for idtext to 3. Set the vertical span for the description label and desctext to 3. Set the horizontal grab for desctext to true. Set the horizontal and vertical fill for desctext to true. On the second composite place three buttons, one label, and then two more buttons. Clear the text of the label. Name the buttons newtransbutton, deltransbutton, edittransbutton, savetransbutton, and canceltransbutton. Set their text to New, Delete, Edit, Save, and Cancel, respectively. Set the enabled property of both savetransbutton and canceltransbutton to false. Convert the buttons to fields by using the convert local to field button. Your shell should now look like this: Creating a Menu: Creating a menu in the SWT Designer is simple. You are not able to create a menu using the free version of the SWT Designer, so if you are using the free version, you will have to create the menu by hand like we did in the Address Book example. We will create a very simple menu with just one dropdown menu and one menu item. Place a MenuBar on the shell. Place a Menu on the menu bar you just created. Set its text to File. Place a MenuItem on the File menu. Set its text to Quit. That is all you have to do to create a simple menu. The original ClientBillingUI also includes an About menu, but we will not cover creating another shell in this example An Eclipse GUI Builder University of Manitoba 72

287 Running the Application: Run the application. As with the Address Book example, the initial window size is probably different from what is desired. To set up the shell to start with the size you specify, right-click on the shell in the Control Tree and select Set Shell Size > Using the setsize() method. Now resize the shell to the desired size. Your application should look like the following when run: Congratulations, you have successfully created a GUI for the Client Billing Application. You have also seen how easy it is to configure layouts and menus in the Designer. The GUI we made has no functionality at all until we add on a database and add some events. This is a task that is left for you. By analyzing the code in ClientBillingUI, it is fairly simple to do and primarily involves copying and pasting. Creating a Swing GUI for the Client Billing Application: Like the above example, we will be creating a GUI for the Client Billing Application using the Designer. The GUI created in this example, however, will be creating using only Swing components. If you have not already looked at the SWT example above, I would suggest you look at it first. The GUI we will be creating in this example will look and function almost identically to the GUI created in the previous example. By looking at the previous example, you will be able to see some of the differences and similarities between the SWT Designer and the Swing Designer. Creating the ClientBillingUI: We need to create a new class for the Swing GUI that we are about to design. In order to distinguish between the different GUIs, we will name this class ClientBillingUISwing An Eclipse GUI Builder University of Manitoba 73

288 To create a new Swing application, select New > Other from the File menu. In the first wizard page, select Designer on the left side and Swing JFrame on the right. Click Next and name the new class ClientBillingUISwing. Click Finish to create the new class An Eclipse GUI Builder University of Manitoba 74

289 Swing allows the use of different look-and-feels. This allows a Swing application to look more like an application created for a specific operating system. Although you cannot currently change the look-and-feel of the application using the Designer, you can see what it would look like by selecting a look-and-feel in the design view. There is a dropdown list above the Content Pane in the design view of the Swing Designer. Since the application uses the Metal look-and-feel by default when it is run, we will use the Metal look-and-feel when we design our application. To change the lookand-feel to Metal, select Metal from the look-and-feel dropdown list. Select the (JFrame) object in the Control Tree and set its title in the Inspector to Client Billing Application. Then set the contentpane s layout to GridBagLayout by selecting GridBagLayout from the Layouts category in the Control Palette and placing it on the contentpane. Creating the Client List JPanel: Add a JPanel to the contentpane. Under the constraints complex property in the Inspector, set the weightx property to 0.25 and the weighty property to 1.0. These properties set the proportions of a component s dimensions, which are compared to other component s proportions. A 1.0 value is typically associated with 100%, where 0.25 is associated with 25%. If 0.0 is used, the component s preferred size is used. Add a JTabbedPane to the right of the JPanel. Add it by placing the mouse cursor on the far right edge of the JPanel. Green bars will surround the JPanel. Click on the far right bar to place the JTabbedPane to the right of the JPanel An Eclipse GUI Builder University of Manitoba 75

290 Select the JTabbedPane and set its weightx property to 0.75 and its weighty property to 1.0. Select the JPanel in the Control Tree. The JPanel should be enclosed in a red border in the Content Pane. There should be two small buttons at the top of the border. Click on the buttons so that arrows appear in them. These buttons set the fill property under the constraints complex property in the Inspector. By clicking on both buttons, we have set the fill property to both. Now do the same thing for the JTabbedPane. In order to make the JPanel look like a group, we need to add a Titled Border. Select Titled Border in the border property in the Inspector. Now select Etched Border in the nested border property. Set the title property to Clients:. Set the layout of the JPanel to GridBagLayout. Add a JScrollPane to the JPanel. JScrollPanes are needed if you want a component to scroll. Some components that often scroll are JLists, JTextAreas, and JTables. Set both the weightx and the weighty properties of the JScrollPane to 1.0. Set the fill property to both An Eclipse GUI Builder University of Manitoba 76

291 Add a JList to the view port of the JScrollPane. Moving the cursor around inside of a JScrollPane while placing a component will highlight the different areas you can place a component. The component that is supposed to scroll is always placed in the view port, which is the center area. Set the variable name of the JList to clientlist. Add a JLabel below the JScrollPane by clicking on the green bar at the bottom of the JScrollPane. Add a JTextField to the right of the JLabel. Add a JRadioButton below the JLabel, and another JRadioButton below the other JRadioButton. Set the JScrollPane s gridwidth property under the constraints complex property to 2. The gridwidth and gridheight properties set the number of columns and rows that a component takes up. Set the JLabel s text property to Filter:. Expand the insets complex property in the constraints complex property and set the left and right properties to 5. The insets properties put some padding around the component. Set the JTextField s variable name to filtertext and clear its text property. Set its fill constraint property to horizontal. Set the variable name of the top JRadioButton to nameradio, set the text property to View by name, set the selected property to true, set the gridwidth constraint to 2, and set the anchor constraint to West. You can set the anchor constraint by dragging the JRadioButton to its desired position on the Content Pane An Eclipse GUI Builder University of Manitoba 77

292 Set the variable name of the bottom JRadioButton to numradio, set the text property to View by ID, set the gridwidth constraint to 2, and set the anchor constraint to West. In order to link the two JRadioButtons together, we have to add them to a ButtonGroup. To create a ButtonGroup, select the ButtonGroup from the Swing Controls section of the Control Palette. Right at the bottom of the Control Tree should be an object called (button groups). Add the ButtonGroup to this object in the Control Tree. A new ButtonGroup named buttongroup should be created. Select the nameradio JRadioButton and select buttongroup from the dropdown list of the buttongroup property. Do the same with the numradio JRadioButton. Now when the application is run, selecting one of the JRadioButtons will deselect the other one. This ensures that only one JRadioButton can be selected at one time. Below is what our completed client list JPanel should look like. Creating a JTabbedPane: We had previously added a JTabbedPane to the contentpane. When a component is added to a JTabbedPane, a new tab appears and that tab contains the component that you added to the JTabbedPane An Eclipse GUI Builder University of Manitoba 78

293 In order to place several components in a tab, a container must be the component added to the JTabbedPane. Select JPanel from the Control Palette and click anywhere inside the JTabbedPane. A tab appears with a JPanel in it. Create a second tab by selecting JPanel from the Control Palette and add it to the JTabbedPane. If there is already a tab on a JTabbedPane, you must place the cursor beside a previously placed tab to add another tab. Set the left tab s title to Clients and the right tab s title to Transactions. The tabs should look like the following: The Clients Tab: Set the layout of the JPanel in the Clients tab to BorderLayout. Add a JPanel to the south section and then add a JPanel to the center section. Set the layout of the JPanel in the south section to GridLayout. Add three JButtons, one JLabel, two JButtons, one JLabel, and one JButton, in that order to the south JPanel. The first JButton may have to be added to the JPanel through the Control Tree because the JPanel will initially be very small. Name the JButtons newclientbutton, delclientbutton, editclientbutton, saveclientbutton, cancelclientbutton, and printtransbutton, in the same order they were placed. Set the text property of the JButtons to New, Delete, Edit, Save, Cancel, and Print, in the same order as above. Expand the margin complex property in the Inspector and set the left and right margins to 4 for each JButton. Set the enabled property for saveclientbutton and cancelclientbutton to false. Clear the text property for the two JLabels. Select each JButton and click on the Convert local to field button. The buttons should look like the following: 12 - An Eclipse GUI Builder University of Manitoba 79

294 Set the center JPanel s layout to GridBagLayout. Add eight JLabels to the center JPanel. Place them one below each other in one column. Add six JTextFields just to the right of the top six JLabels. All the JTextFields should be in one column. Add two JScrollPanes below the JTextFields and beside the bottom two JLabels. There should now be eight rows and two columns. Set the text property of the JLabels to Account ID:, First Name:, Surname:, Date of Birth:, Phone Number:, Address:, Address:, and Miscellaneous Information:, from top to bottom. Set all the JLabels anchor constraint to West except for the Miscellaneous Information JLabel, which should be set to North. Set the top, left, bottom, and right insets of each JLabel to 5. Set the weighty constraint of the Miscellaneous Information JLabel to 1.0. Set the variable names of the JTextFields to acctidtext, fnametext, snametext, dobtext, phonetext, and text, from top to bottom. Clear the text property of all the JTextFields. Set the weightx constraint of all the text fields to 1.0 and the fill constraint to horizontal. Set the editable property of all the JTextFields to false. Set the fill constraint of both JScrollPanes to horizontal. Set the bottom JScrollPane s anchor constraint to North. Add a JTextArea to the view port of both JScrollPanes. Set the variable name of the JTextArea in the top JScrollPane to addresstext and the other JTextArea to miscinfotext. Clear the text property of both JTextAreas. Set the editable property of both JTextAreas to false. In Swing, making a JTextArea non-editable does not color it gray like the JTextFields. If you wish to do this, you will have to do this yourself. The finished Clients tab should now look like the following: 12 - An Eclipse GUI Builder University of Manitoba 80

295 The Transactions Tab: Double-click the Transactions tab to view the contents of it. Set the layout of the JPanel in the Transactions tab to BorderLayout. Add a JPanel in the south section of the JPanel in the Transactions tab and then add another JPanel in the center section. Set the layout of the south JPanel to GridLayout. Add three JButtons, one JLabel, and two JButtons, in that order. The first JButton may have to be added to the JPanel through the Control Tree. Name the JButtons newtransbutton, deltransbutton, edittransbutton, savetransbutton, and canceltransbutton, in the same order you added them. Set their text properties to New, Delete, Edit, Save, and Cancel, in order. Set the left and right properties in the margin complex property to 4 for each JButton. Set the enabled property to false for savetransbutton and canceltransbutton. Clear the text property for the JLabel. Select each JButton and click on the Convert local to field button. The buttons should look like the following: Set the layout of the center JPanel to GridBagLayout. Add four JLabels, one below the other, all in one column. Add four JTextFields to the right of the JLabels, all in one column. Add one JLabel to the right of the third JTextField from the top. Add a JScrollPane to the right of one cell up from the right-most JLabel. Add a JScrollPane above the top-left JLabel. The reason we did not add the last JScrollPane first was because it would have initially been very small and it would have been hard to add another component below it. Set the text property of the JLabels to Total:, ID:, Amount:, Date:, and Description:, in the order you created them. Set the anchor constraint of all the JLabels to West. Set the top, left, bottom, and right insets of all the JLabels to 5. Name the JTextFields totaltext, idtext, amttext, and datetext, from top to bottom. Clear the text of all the JTextFields. Set the weightx constraint of totaltext to Set the fill constraint of all the JTextFields to horizontal. Set the editable property of all the JTextFields to false. Set the gridheight constraint of the right JScrollPane to 3, its weightx constraint to 0.75, and its fill constraint to both. Add a JTextArea to the view port of the right JScrollPane. Name it desctext. Clear its text property, set its editable property to false, its linewrap property to true, and its wrapstyleword property to true An Eclipse GUI Builder University of Manitoba 81

296 The section we just created is shown below. The JTextFields look smaller than they should be. They shrunk when we set the JTextArea s linewrap property to true. This has to do with how the layout works and should appear correctly after we finish configuring the rest of the components. Set both the weightx and weighty constraints of the top JScrollPane to 1.0. Set its fill constraint to both and its gridwidth constraint to 4. Add a JTable to the view port of the top JScrollPane. Name the JTable infotable. Select the JTable and click on the Open definition button. Add the following line in the JTable s block of code: infotable.gettableheader().setreorderingallowed(false); This prevents a user from rearranging the columns. A bit further down we will be using the column number to determine which column is which. If the columns are rearranged, it changes the index of the columns. The finished Transactions tab should look like the following: 12 - An Eclipse GUI Builder University of Manitoba 82

297 Filling a JTable with values is not as simple as it is in SWT. In SWT you can assign a String to each cell in a Table, whereas in Swing, a JTable functions similarly to a JFace TableViewer. To create a table in Swing, you must create a model. Fortunately, the Swing Designer creates the skeleton of a table model for us. To create the table model, double-click on the model property of the JTable. This creates a new inner class called InfoTableTableModel. The following is the contents of that class. class InfoTableTableModel extends AbstractTableModel { public final String[] COLUMN_NAMES = new String[] { ; public int getrowcount() { return 0; public int getcolumncount() { return COLUMN_NAMES.length; public String getcolumnname(int columnindex) { return COLUMN_NAMES[columnIndex]; public Object getvalueat(int rowindex, int columnindex) { return null; The table model does not really do anything. To make the table functional, make the InfoTableTableModel class look like the following: class InfoTableTableModel extends AbstractTableModel { private ArrayList transactions = new ArrayList(); private final String[] COLUMN_NAMES = new String[] { "ID", "Amount", "Date", "Description" ; public int getrowcount() { return transactions.size(); public int getcolumncount() { return COLUMN_NAMES.length; public String getcolumnname(int columnindex) { return COLUMN_NAMES[columnIndex]; public Object getvalueat(int rowindex, int columnindex) { Transaction transaction = (Transaction)transactions.get(rowIndex); switch (columnindex) { case 0: //ID column return new Integer(transaction.transactionID); case 1: //Amount column return new Integer(transaction.amount); case 2: //Date column return transaction.date; case 3: //Description column return transaction.description; default: return null; public void addrow(transaction transaction) { transactions.add(transaction); firetablerowsinserted(transactions.size() - 1, transactions.size() - 1); 12 - An Eclipse GUI Builder University of Manitoba 83

298 The following also needs to be added to the list of imports. import java.util.arraylist; The above creates an ArrayList of Transactions to hold the data of the table. Note that the Transaction class from the Client Billing Application must be available. The number of rows is the number of Transactions in the ArrayList. The column names are stored in a String array called COLUMN_NAMES. The getvalueat() method returns an object based on the row and column indexes that were passed. The table calls this method and then calls the getstring() method of the returned object to display the values in the table. The addrow() method is a method that was added to the class to easily add Transactions to the table. It adds the passed Transaction to the ArrayList and then calls firetablerowsinserted() to notify the table that rows have been inserted. The parameters of firetablerowsinserted() are the indexes of the first and last rows inserted, inclusive. You can add a row to the table by using the following code: ((InfoTableTableModel)(infoTable.getModel())).addRow(t); where t is the Transaction object that you want to add. In order to add extra functionality to the table, such as sorting, the table model would simply have to be extended to support the desired functions. We will not cover that here since it is beyond the scope of this tutorial. When you run the application, you can see the columns that we have created An Eclipse GUI Builder University of Manitoba 84

299 Creating a Menu: To create a menu bar at the top of the application, we have to add a JMenuBar to the JFrame. Select JMenuBar from the Menu Controls category of the Control Palette and place your cursor over the application title bar. The area the menu bar will go is highlighted. Add a JMenu to the JMenuBar you just added. Set its text property to File. Add a JMenuItem to the File menu. Set its text to Quit. Shown below is the final GUI, including a menu An Eclipse GUI Builder University of Manitoba 85

300 Running the Application: You can run just the Swing GUI because the Swing Designer creates a main() method. Because the GUI uses just Swing and AWT components, you do not need to add any JAR files to your projects build path. The GUI currently does not have any useful functionality. No information is displayed and the buttons do nothing when they are clicked. Making this GUI functional would be similar to making the SWT GUI functional. However, there would be some differences. Similar widgets for SWT and Swing may have different properties and may access data differently. An example is a table. Getting a simple table working in Swing requires a lot more effort than getting a simple table working in SWT. To plug the Swing GUI into an application, you only need to place the code that is in the main() method of the ClientBillingUISwing class into another method in another class that is supposed to open the GUI. Summary: This tutorial has described the majority of the features of the free and professional versions of the Designer. We have gone through an example of creating a GUI for a simple Address Book application using the free version of the SWT Designer. Through this example we have learned how to create a GUI as well as how the Designer generates code. We have also gone over a more advanced example in both SWT and Swing using the professional version of the Designer where we used layout managers, tabbed folders, and menus. The easiest way to get familiar with this easy to use GUI designer is to play around with it. There is additional documentation as well as some demos available at An Eclipse GUI Builder University of Manitoba 86

301 Refactoring in Eclipse 1, 2 by Raphael Enns, University of Manitoba, Winnipeg, Manitoba, Canada Last revised: February 25, 2004 Overview: In this tutorial, we will discuss refactoring in Eclipse. We will describe what refactoring is and why it is used. We will take a look at each refactoring that Eclipse allows you to do and see when and where to use the refactorings. What is Refactoring? Refactoring is the process of changing the structure of a program while maintaining all of its functionality. There are many types of refactorings that you can do such as renaming a class, changing a method signature, or extracting some code into a method. With each refactoring, you carry out a number of steps that keep your code consistent with the original code. Why Refactoring is Important: When refactoring by hand, it is easy to introduce errors into your code such as spelling mistakes or missing a step in the refactoring. To prevent and quickly fix these errors, thorough testing should be performed before and after each refactor. You may wonder if refactoring is worth going through all this. There are several reasons why refactoring should be used. You may want to update a program that is poorly coded. Perhaps none of the original design team is present and no one on the current design team understands the code. In order to update it, you will have to redesign and restructure the program to fit what you want it to do. Another reason is that you may want to add a feature that the original design cannot accommodate. In order to add it, you will have to restructure the code. The third reason is that an automatic refactoring tool, such as the refactorings in Eclipse, can generate code for you. 1 This work was funded by an IBM Eclipse Innovation Grant. 2 Raphael Enns and David Scuse Refactoring in Eclipse University of Manitoba Tutorial

302 By using refactorings, you can easily change the structure of a program to what makes logical sense while rewriting code as little as possible and still keeping its functionality. If refactoring is used on a regular basis to constantly keep a good structure, less time will be needed to fix any bugs and it will be easy to add new code to the design. Testing: Testing your code is very important when refactoring. Because refactoring changes the structure of your code, you must make sure that the resulting code functions the same way as the code did before the refactoring. When doing the refactorings by hand, a good suite of tests is a must. When using an automated tool to refactor, you should still test, but it need not be quite as often. This is because the tool will not make some of the errors you might make when you refactor by hand, such as spelling mistakes. Use JUnit to easily create tests for your application in Eclipse. For more information on creating tests using JUnit, see the tutorial Using JUnit in Eclipse. Refactoring in Eclipse: The Java part of Eclipse, JDT, is able to perform several types of automatic refactorings on Java projects, classes, and their members. There are several ways to quickly select a refactoring for an element in a Java project. To perform a refactoring for one or more elements, you must have the element(s) selected. You can select elements in several views including the Outline view and Package Explorer view. To select multiple elements in a view, hold down Ctrl or Shift and then select the elements. Another way to select an element is to highlight it in the editor or place your caret in it in the source file (a caret is the blinking cursor displaying where the text will go when you type). After you have selected the element(s) you want to refactor, either choose a refactoring from the dropdown Refactor menu, or right-click and choose a refactoring from the Refactor submenu of the popup menu. There are also shortcut keys that can be used for several of the refactorings. Some refactorings can be applied to any type of element. Other refactorings only apply to certain types of elements such as a method or a class. There is a table at the end of this tutorial listing the refactorings, the elements each refactoring can be applied to, as well as any shortcut keys for the refactorings. Refactoring in Eclipse University of Manitoba Tutorial

303 All of the refactorings in Eclipse are able to be previewed before performing the refactor. Simply click on the Preview button in the refactoring dialog and view all the changes that will occur. The only refactoring that does not have a preview button is Pull Up. The preview pane will always appear on the last screen in the Pull Up refactoring wizard. Individual changes that will result from the refactoring can be deselected in the preview pane so that they will not occur. Undo and Redo: There are Undo and Redo items in the Refactor menu. These are not the same as the Undo and Redo items in the Edit menu. The Undo and Redo items in the Edit menu only modify the current file, even if a refactoring modified several files. The Undo and Redo items in the Refactor menu will undo or redo any changes made in all the files modified during a refactoring. The Undo and Redo items in the Refactor menu also have some restrictions on their use. You cannot undo or redo a refactoring if any files have been modified and saved after a refactoring, regardless if they were modified in the refactoring. If a file was modified in a refactoring then modified outside of a refactoring but not saved, an error message will appear saying that you must revert unsaved files when you try to undo or redo a refactoring. As long as you take note of the restrictions above, you can undo and redo refactorings as much as you want. You can even compile and run your program as well as run tests and still be able to undo the refactorings as long as you do not modify and save any files. Types of Refactoring in Eclipse: If you look in the Refactor dropdown menu in Eclipse, you will notice four sections. The first section has Undo and Redo in it and the other three sections contain the three different types of refactorings available in Eclipse. The first type contains refactorings that change the physical structure of the code and classes such as Rename and Move. The second type contains refactorings that change the code structure on a class level such as Pull Up and Push Down. The third type contains refactorings that change the code within a class such as Extract Method and Encapsulate Field. The sections and their refactorings are shown below. Refactoring in Eclipse University of Manitoba Tutorial

304 Type 1 Physical Structure Rename Move Change Method Signature Convert Anonymous Class to Nested Convert Nested Type to Top Level (Eclipse 2 only) Move Member Type to New File (Eclipse 3 only) Type 2 Class Level Structure Push Down Pull Up Extract Interface Generalize Type (Eclipse 3 only) User Supertype Where Possible Type 3 Structure inside a Class Inline Extract Method Extract Local Variable Extract Constant Introduce Parameter (Eclipse 3 only) Introduce Factory (Eclipse 3 only) Encapsulate Field Rename: The Rename refactoring does just that, it renames a Java element. Although you can rename Java files and Java elements by hand, this will not update any references to those files and elements. You would have to search through the files in your project and replace the appropriate references by hand. There is always the chance that you might miss a reference or replace a wrong reference. The Rename refactoring will intelligently update all of the appropriate references in a project for you. Sometimes the name of a Java element may not be clear or its function may have changed. In order to maintain the readability of the code, the name of the element should be updated. Using the Rename refactoring, it is quick and easy to rename the element and update all references to it. To rename a Java element, select the element in either the Package Explorer view, the Outline view, or the Java source file and either select Rename from the Refactor menu or use the shortcut key, Alt + Shift + R. The Rename dialog will appear. You can then enter in the new name and select whether to update references to the element. Refactoring in Eclipse University of Manitoba Tutorial

305 Clicking on the Preview button will bring up the preview screen where you can see and modify what changes will be made. Move: Move is very similar to Rename. It is used to move elements from one place to another. It is primarily used to move classes to different packages. To move an element, select the element, select Move from the Refactor menu or use the shortcut key, Alt + Shift + V, and select the destination in the window that appears. Again, you can click on Preview to examine the changes, or simply press OK to carry out the refactoring without previewing. Refactoring in Eclipse University of Manitoba Tutorial

306 Change Method Signature: The Change Method Signature refactoring is able to change parameter names, parameter types, the parameter order, the return type, and the method s visibility. Parameters can also be added or removed. To change the signature of a method, select the method and select Change Method Signature from the Refactor menu. The Change Method Signature dialog will appear. Refactoring in Eclipse University of Manitoba Tutorial

307 From the dialog you can set the visibility, return type, and parameters of the method. Parameters can be added, edited, moved, and removed by clicking on the buttons on the right. The default value is used when a new parameter is added. This value is then placed in the location of the new parameter in any calls to the method being changed. Changing the signature of a method can cause problems in the method. If any problems are found, they will be flagged when you click Preview or OK. Convert Anonymous Class to Nested: An anonymous class allows you to instantiate a class implementing an abstract class or interface without having to give it a name. This is often used in creating listeners for a user interface. When an anonymous class gets too large, it should be made into its own class. To do this, place the caret inside of an anonymous class and select Convert Anonymous Class to Nested from the Refactor menu. This opens the Convert Anonymous Class to Nested Class dialog where you can set the new name of the class and its visibility. Convert Nested Type to Top Level (Eclipse 2 Only): This refactoring converts a nested class into a top level class. A new Java file is created with the previously nested class in it. To convert a nested class to a top level class, select the nested class and select Convert Nested Type to Top Level from the Refactor menu. A dialog will appear asking for the name of the enclosing instance. Refactoring in Eclipse University of Manitoba Tutorial

308 Because the nested class previously had access to the outer class members, a new instance of the outer class is made to give the new class access to those members. Move Member Type to New File (Eclipse 3 Only): This refactoring is exactly the same as the Convert Nested Type to Top Level refactoring from Eclipse 2, except it allows you to specify whether or not you want the enclosing instance to be created. Push Down: The Push Down refactoring moves selected methods and fields from a class to all the classes that directly extend it. Any methods that are pushed down can optionally be left as an abstract declaration. A Push Down refactoring can be useful for restructuring the design of a project. Selecting one or more methods or fields and then selecting Push Down from the Refactor menu will bring up the Push Down dialog. Refactoring in Eclipse University of Manitoba Tutorial

309 Individual methods and fields can be selected from the table. All selected elements are then pushed down to all the subclasses of the current class. When the Add Required button is clicked, any methods and fields that are found to be required by the elements already checked in the table are also checked. This will not always add every element that is required, so you should double-check to make sure that everything that is needed is checked in the table. The Edit button is enabled when one or more methods are selected in the table in the Push Down dialog. When the Edit button is clicked, the Edit Members dialog appears. In this dialog you can choose to leave an abstract declaration in the current class for the selected method(s) or to simply remove the method declaration(s) in the current class. Double-clicking on a checked method in the table in the Push Down dialog will also bring up the Edit Members dialog. Clicking on a method under the Action column in the table will cause a dropdown list to appear where you can also select between leave abstract declaration and push down. Press Enter after selecting a value in the list to apply the value. Pull Up: The Pull Up refactoring is similar to the Push Down refactoring in that it involves moving selected methods and fields between classes. The Pull Up refactoring, however, moves methods and fields from a class to one of its superclasses. Selecting one or more methods or fields and then selecting Pull Up from the Refactor menu will bring up the Pull Up wizard. The Select destination class combo box contains a list of all the superclasses that the current class extends. The superclasses may be several levels removed from the current class. You are only able to pull up the selected fields and methods to one of the superclasses. Refactoring in Eclipse University of Manitoba Tutorial

310 If any selected methods have their action set to declare abstract in destination, the Create necessary methods in non-abstract subclasses of the destination class check button is enabled. When this button is checked, all subclasses of the destination class who do not have or inherit the selected method that is to be declared as abstract will have method stubs for that abstract method added to them. As in the Push Down refactoring, selecting one or more methods and clicking on the Edit button or double-clicking on a method will open the Edit Members dialog. The two options are pull up and declare abstract in destination. The pull up action will simply copy the members to the superclass and give the option to remove the members from the current class. The declare abstract in destination action will create an abstract method in the superclass, make the superclass abstract if it is not already, and leave the method in the current class. As in the Push Down refactoring, clicking in the Action column of a selected method will cause a dropdown list to appear where you can select one of the two actions. Press Enter after selecting an action in the list to apply the action. Refactoring in Eclipse University of Manitoba Tutorial

311 If any selected method has its action set to pull up, clicking on Next will display the wizard page allowing you to select which methods you wish to remove from the current class. Only methods with their action set to pull up are displayed. If a method in this page is checked, it will be completely removed from the current class. Clicking on elements in the tree on the left side of the page shows the source code for that element on the right side of the page. Refactoring in Eclipse University of Manitoba Tutorial

312 Clicking Next on the first wizard page without any methods set to pull up, or clicking Next on the wizard page where you can remove selected methods will bring you to the preview wizard page. This page is similar to the other preview pages and works the same way. Clicking on the Finish button at any time during the wizard will do the refactoring with the defaults for any pages that would be displayed by clicking on the Next button. Extract Interface: The Extract Interface refactoring allows you to create an interface from an existing class. You are able to select which methods from the current class will be included in the interface. To open the Extract Interface dialog, select a class and then select Extract Interface from the Refactor menu. In the Extract Interface dialog, type the desired name for the interface and select the methods that you want to be in the interface. Only public methods are listed in the dialog. Checking the Change references to the class [current class name] into references to the interface (where possible) check button will change any references to the current class to the interface if it is able to. Click on OK to apply the refactoring. Generalize Type (Eclipse 3 Only): The Generalize Type refactoring changes the type of an object in its declaration to one of its supertypes. Select a declaration of a variable, parameter, field, or method return type and Generalize Type from the Refactor menu. In the Generalize Type dialog, select the new type of the object and click OK to apply the refactor. Refactoring in Eclipse University of Manitoba Tutorial

313 Use Supertype Where Possible: The Use Supertype Where Possible refactoring will replace references to a certain type of object by one of its supertypes. To open the Use Super Type Where Possible dialog, select a class and then select User Supertype Where Possible from the Refactor menu. In the dialog, select the supertype to use. If the Use the selected supertype in instanceof expressions check button is checked, instanceof expressions will also be modified during the refactoring. Eclipse 3 does not have the check button and will always modify the instanceof expressions during the refactoring. Inline: The Inline refactoring takes a reference to a method, static final field, or a local variable and replaces it with its code or value. For example, if you inline a method call, the call will be replaced by the body of code in the called method. To inline a method, static final field, or a local variable, select the element and select Inline from the Refactor menu. You can also use the shortcut key Alt + Shift + I. In the Inline dialog, you can select whether to inline All invocations or Only the selected invocation. If you inline all invocations, you also have the option to delete the declaration itself. Below is shown the dialog to inline a method. Similar dialogs are available for static final fields and local variables. Refactoring in Eclipse University of Manitoba Tutorial

314 Extract Method: If a method does more than one distinct operation, is too long, or if some code in a method is used several times, it may be beneficial to extract a section of the method into its own method. It is easy to do this using the Extract Method refactoring. To extract a method, select the lines of code you want to extract and select Extract Method from the Refactor menu or use the shortcut key Alt + Shift + M. In the Extract Method dialog, type in the name of the new method, select the appropriate access modifier and choose whether you want thrown runtime exceptions to be added to your method signature. The Signature preview line on the bottom of the dialog displays what your new method s signature will look like. Extract Local Variable: Using a variable instead of an expression can have several benefits. It may increase performance if the same expression is used in several places and it can also make the code easier to read and understand. To extract an expression to a local variable, select the expression and then select Extract Local Variable from the Refactor menu. You can also use the shortcut key Alt + Shift + L. Refactoring in Eclipse University of Manitoba Tutorial

315 Type in the new variable s name and select whether you want to replace all expressions by the variable and whether you want the variable to be final. As with Extract Method, a preview of the variable s signature is displayed at the bottom of the dialog. Extract Constant: The Extract Constant refactoring is very similar to the Extract Local Variable refactoring. The only differences are that the Extract Constant refactoring allows you to choose what access modifier you want the constant to have and that it places the constant as a field in the class. Introduce Parameter (Eclipse 3 Only): Introduce Parameter creates a new parameter in a method and then replaces an instance of a field or local variable with the new parameter. To use the Introduce Parameter refactoring, select a reference to a field or a local variable in a method and then select Introduce Parameter from the Refactor menu. Refactoring in Eclipse University of Manitoba Tutorial

316 Introduce Factory (Eclipse 3 Only): A factory is a method which creates a new object and then returns that object. You can create a factory by selecting the constructor you want to create a factory for and then selecting Introduce Factory in the Refactor menu. In the Introduce Factory dialog, type the desired factory method name and which class you want the factory to appear in. Then choose whether you want the selected constructor to be made private. After you click OK, a new method with the name you specified will appear in the specified class. It will create a new instance of the current class using the selected constructor. The method s return value will be the new instance it created. Convert Local Variable to Field: The Convert Local Variable to Field refactoring moves a declaration of a variable from inside a method to the top of the class where it is then visible to the entire class. Select a local variable and then select Convert Local Variable to Field in the Refactor menu to bring up the Convert Local Variable to Field dialog. Refactoring in Eclipse University of Manitoba Tutorial

317 In the Convert Local Variable to Field dialog, type in the new name for the field, select its access modifier and specify where the field is to be initialized. The Initialize in radio buttons are only available if the variable is initialized on creation. The Declare field as static and Declare field as final check buttons are enabled depending on where you choose to initialize the field. Encapsulate Field: To use proper object orientated coding practices, you should make your fields private and then create accessors and mutators to access the fields. It can take a bit of time to do this mundane task. It is easy to create the accessors and mutators of a field using the Encapsulate Field refactoring. Simply select a field or a reference to a field and then select Encapsulate Field from the Refactor menu. Refactoring in Eclipse University of Manitoba Tutorial

318 In the Self Encapsulate Field dialog, type in the desired getter and setter method names and then select the method where you want the new methods to appear after. Different access modifiers may be available depending on what the access modifier of the field is. Applying the Encapsulate Field refactoring will create two new methods, set the access modifier of the field to private, and will change references to the field to references to the new methods. List of Refactorings: Below is a table of all the refactorings, the different types of Java elements each refactoring is available on, and any shortcut keys for the refactorings. Information from the table was taken from the Eclipse Java help. Name Elements Refactoring is Available On Keyboard Shortcut Undo Can be performed after a refactoring. Alt + Shift + Z Redo Can be performed after an undo of a refactoring. Alt + Shift + Y Rename Is available on methods, fields, local variables, method parameters, objects, classes, packages, source folders, and Alt + Shift + R projects. Move Is available on one instance method (which can be moved to a component), one or more static methods, static fields, objects, Alt + Shift + V classes, packages, source folders and projects. Change Method Is available on methods. Signature Convert Anonymous Class to Is available on anonymous inner classes. Nested Convert Nested Type to Top Level Is available on nested classes. (Eclipse 2) Move Member Type to New File Is available on nested classes. (Eclipse 3) Push Down Is available on one or more methods and fields declared in the same class. Pull Up Is available on one or more methods, fields and nested classes declared in the same class. Extract Interface Is available on classes. Generalize Type (Eclipse 3) Is available on declarations of an object. Refactoring in Eclipse University of Manitoba Tutorial

319 Use Supertype Where Is available on classes. Possible Inline Is available on methods, static final fields and local variables. Alt + Shift + I Extract Method Is available on selections of code. Alt + Shift + M Extract Local Variable Extract Constant Introduce Parameter (Eclipse 3) Introduce Factory (Eclipse 3) Convert Local Variable to Field Encapsulate Field Is available on selections of code that can be resolved to local variables. Is available on static final fields and selections of code that can be resolved to static final fields. Is available on references to fields and local variables in a method. Is available on constructors. Is available on local variables. Is available on fields. Alt + Shift + L Summary: This tutorial described the refactorings currently available in Eclipse. These refactorings are easy to use and can make restructuring your code easier and safer. They can also help you generate code in order to increase your productivity. By using the automatic refactoring tools included with Eclipse, you will have a more enjoyable coding experience. Note: Applying some refactorings that modify the structure of classes such as Push Down and Pull Up may not modify the other classes in a project. In this case you will have to make sure that all references to the modified elements are updated. This is why a good test suite is needed, although you may have to update references in the test classes as well. An example of this is using the Push Down refactoring on a method. If another class has an instance of the class that originally had the method and makes a call to the method, after the Push Down refactoring there will be an error in the calling class because the method is no longer found in the original class. Refactoring in Eclipse University of Manitoba Tutorial

320 Design Patterns and CodePro 1, 2 by Raphael Enns, University of Manitoba, Winnipeg, Manitoba, Canada Last revised: March 10, 2004 Overview: In this tutorial, we will explain what design patterns are and how they are useful. This tutorial will describe several design patterns in detail, giving a simple example in Java for each. We will also look at a plug-in for Eclipse that helps create design patterns. About Design Patterns: After programming several projects using object orientation, you may find that you are programming similar structures again and again. In the book Design Patterns by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, the authors describe 23 design patterns that they have found to be recurring in object orientated programming. The four authors of Design Patterns are nicknamed the Gang of Four (GoF) and the design patterns in the book are considered to be GoF design patterns. Design patterns are an aid in programming in that they allow programmers to reuse a lot of code and structure instead of having to continually recode similar designs. This leads to faster development and higher-quality code. Design Pattern Categories: The book Design Patterns has three categories of design patterns. They are Creational Patterns Structural Patterns Behavioral Patterns 1 This work was funded by an IBM Eclipse Innovation Grant. 2 Raphael Enns and David Scuse Design Patterns and CodePro University of Manitoba Tutorial

321 Creational patterns involve different ways of instantiating objects. They keep the rest of the program separate from how objects are created and represented. The GoF creational patterns are Abstract Factory, Builder, Factory Method, Prototype, and Singleton. Structural patterns describe how different classes are structured together. This involves how different classes are able to access each other and how the hierarchy of objects is set up. The GoF structural patterns are Adapter, Bridge, Composite, Decorator, Façade, Flyweight, and Proxy. Behavioral patterns involve how objects interact with each other. This primarily involves splitting up functionality between classes and accessing this functionality without necessarily knowing how the system is structured. The GoF behavioral patterns are Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, and Visitor. Although new categories have been formed in addition to the three mentioned above, this tutorial will only look at a selection of GoF design patterns that are in the three categories mentioned above. Singleton: The singleton design pattern is a creational pattern and is one of the simplest design patterns. A singleton class will only allow one instance of itself to be instantiated. It checks whether an instance has been created already and if so returns that instance. Shown below is the basic structure of a singleton class. public class Singleton { private static Singleton instance; private Singleton() { public static Singleton getinstance() { if (instance == null) instance = new Singleton(); return instance; In the singleton class there is a private static field of the singleton instance. The null constructor is made private so that a calling class cannot use the constructor to create an instance. The only way to get an instance of the singleton class is through the public static getinstance() method. The calling class would get the singleton instance with the following line: Singleton instance = Singleton.getInstance(); Design Patterns and CodePro University of Manitoba Tutorial

322 The getinstance() method checks to see if an instance has been created already by testing if its instance field is null. If it is null, an instance has not yet been created so the instance field is then instantiated. If it is not null, an instance has already been created. The instance field is then returned. Once an instance has been created, the same instance will always be returned by the getinstance() method. A slightly different way of implementing a singleton class is to change the field declaration to private static final Singleton instance = new Singleton(); Using this approach, an instance of the singleton class is always created. The test to see if the instance has been created can then be removed so that the only thing the getinstance() method does is return the instance field. Factory Method: The factory method design pattern is a creational pattern that uses the factory principle. The factory principle involves a method which creates an instance of an object and then returns the object. Parameters may be passed to the method which can be used to select the type of object to return. The factory method design pattern uses inheritance to determine the correct object to instantiate. A base creator class is created that may be abstract. Concrete creator classes extend the creator class. The factory method is declared in the creator class. If the factory method is abstract, all of the creator class subclasses must also have that method. If the factory method is not abstract, the subclasses may override it if necessary. A class may make an instance of one of the concrete creator classes. Then the class can call the concrete creator class factory method to get the appropriate object. For an example, suppose we have two classes we want to make instances of, Product1 and Product2. To be able to receive an instance of either of these two classes, they must both extend or implement the same class or interface. We will create an interface called Product that Product1 and Product2 will implement. Next we will create the base creator class. We will create an abstract class called Creator, which is shown below. It will have one abstract method called getproduct(). public abstract class Creator { public abstract Product getproduct(); Design Patterns and CodePro University of Manitoba Tutorial

323 We will now create two classes that extend Creator. We will call these classes Product1Creator and Product2Creator. Each one has a getproduct() method that returns the appropriate Product type. Product1Creator is shown below and Product2Creator is identical except the getproduct() method returns a Product2 object. public class Product1Creator extends Creator { public Product getproduct() { return new Product1(); To create a new Product, a class must first have an instance of either Product1Creator or Product2Creator. Then they simply call the getproduct() method of that instance and they will receive the appropriate object. In the example above there is a one-to-one mapping between the creator classes and the product classes. This need not be the case. Several creator classes may return the same product class or a creator class may return several types of product classes, depending on parameters passed. The factory method design pattern is used when a class is unable to anticipate the exact object it must create. Adapter: The adapter design pattern is a structural pattern that allows classes to work together even though they have incompatible interfaces. The adapter pattern converts one interface into another interface that is required by the associated class. The adapter design pattern is often used in the following scenario. You have a class already created that you wish to use. However, the application does not expect the interface of your class. It may expect an entirely different interface. To allow the application to use your class, an adapter needs to be made. The adapter receives requests from the application and then converts those requests to how your class is set up. In this way, the application thinks it is using a compatible class and you are able to use your class. To use the adapter pattern, you need to create an interface for the expected type. This interface is called the target interface. In our target interface shown below we have two methods that need to be implemented, add(string s) and remove(string s). These are the methods that the application expects to see. Design Patterns and CodePro University of Manitoba Tutorial

324 public interface Target { public void add(string s); public void remove(string s); The incompatible class that you wish to use is called the adaptee class. For the example we will say that our adaptee class has two methods, additem(string s) and deleteitem(string s), that add and delete elements from a vector. The adaptee class is shown below. import java.util.vector; public class Adaptee { private Vector v; public Adaptee() { v = new Vector(); public void additem(string s) { v.addelement(s); public void deleteitem(string s) { v.removeelement(s); To use the adaptee class, even though the application expects the add() and remove() methods, we create an adapter class that implements the target interface. The adapter class creates an instance of the adaptee class and when the target methods are called, the appropriate adaptee methods are called by the adapter. The adapter class is shown below. public class Adapter implements Target { private Adaptee adaptee; public Adapter(Adaptee adaptee) { this.adaptee = adaptee; public void add(string s) { adaptee.additem(s); public void remove(string s) { adaptee.deleteitem(s); Now if you want to use your class in your application, create an instance of the adapter and then call the methods that the application requires. Design Patterns and CodePro University of Manitoba Tutorial

325 The type of adapter shown above is the object adapter. In a slightly different form of adapter, called the class adapter, the adapter class extends the adaptee class and then implements the target interface. Since the adapter is a subclass of the adaptee, it can access its methods without having to first create an instance of the adaptee. Another common use of adapters is when you wish to implement an interface but do not need all parts of it. This often occurs while using event listeners in GUI design. For example, if you wish to implement the SelectionListener interface in SWT, you have to implement the methods widgetselected() and widgetdefaultselected() even if you only want to use one of them. If you use SelectionAdapter instead of SelectionListener, you only have to implement the methods that you want because the SelectionAdapter implements the SelectionListener and creates empty methods for widgetselected() and widgetdefaultselected(). Composite: The composite design pattern is a structural pattern and is used when you want objects to be either components or containers that can hold other components. This is similar to a tree design where the leaf nodes are the components and the non-leaf nodes are the containers. A common place to find the use of composites is in GUI widgets. SWT has a widget called composite which is able to hold other widgets, including other composites. Composites are able to be created in several ways. Sometimes you may allow leaf nodes to become non-leaf nodes by adding children to them, though usually leaf nodes are restricted from having children. You can also set up the structure of inheritance in different ways. In our example we will restrict the non-leaf nodes from having children. We will have an abstract component class with a concrete component class that extends it. The composite class extends the concrete component class. import java.util.nosuchelementexception; import java.util.vector; public abstract class AbstractComponent { protected AbstractComponent parent = null; protected Vector children = new Vector(); public AbstractComponent getparent() {return parent; public abstract AbstractComponent getchild(int index) throws NoSuchElementException; public abstract void addchild(abstractcomponent child) throws NoSuchElementException; public abstract void removechild(abstractcomponent child) throws NoSuchElementException; Design Patterns and CodePro University of Manitoba Tutorial

326 Shown above is the abstract component class. It has a vector to hold the children, a parent, a method to get the parent and several abstract methods that are for performing operations on an object s children. Since we want to restrict the leaf nodes from having children, we add throwable exceptions to the abstract methods. The component class extends the abstract component class. Since components are restricted from having children, any methods that perform operations on children throw an exception. Below is shown a basic component class. import java.util.nosuchelementexception; public class Component extends AbstractComponent { public void addchild(abstractcomponent child) throws NoSuchElementException { throw new NoSuchElementException("Cannot add child to leaf"); public void removechild(abstractcomponent child) throws NoSuchElementException { throw new NoSuchElementException("Cannot remove child from leaf"); public AbstractComponent getchild(int index) throws NoSuchElementException { throw new NoSuchElementException("Cannot get child from leaf"); The composite class extends the concrete component class. Composites are allowed to have children, so the methods performing operations on children are properly implemented. Below is shown a basic composite class. import java.util.nosuchelementexception; public class Composite extends Component { public void addchild(abstractcomponent child) throws NoSuchElementException { children.addelement(child); public void removechild(abstractcomponent child) throws NoSuchElementException { children.removeelement(child); public AbstractComponent getchild(int index) throws NoSuchElementException { return (AbstractComponent) children.elementat(index); Design Patterns and CodePro University of Manitoba Tutorial

327 To add individual components and composites to the example above, simply make classes that extend the component and composite classes. In a real program, you would probably have many more fields and methods in your classes to make them functional. Another way of structuring the composite design pattern is to have an abstract class for the components and an abstract class for the composites that extends the abstract component class. Then all components would extend the abstract component class and all composites would extend the abstract composite class. Command: The command design pattern is a behavioral pattern that allows you to create a command as an object and then execute it as necessary. This pattern is useful if you want to create undo / redo operations, log operations, or execute commands at a later time. A command interface is necessary for this pattern. For an object to be a command object, it must implement a method that will execute its command. Shown below is a simple command interface with one method that needs to be implemented, execute(). public interface Command { public void execute(); Any classes that are to be commands must now implement the command interface. Below is shown a simple command that prints Hello World! to the console when the command is executed. public class HelloCommand implements Command { public void execute() { System.out.println("Hello World!"); You can execute this command by creating an instance of HelloCommand and then by calling its execute method. To create a history of commands that would be useful for undo / redo and logging operations, you would need to have a command manager or command handler class. This class would receive all the commands, save the command in a history data structure, and then execute the command. The history could then be used to undo and redo operations or to resume operations up to the current point in case of a crash. Design Patterns and CodePro University of Manitoba Tutorial

328 Iterator: The iterator design pattern is a behavioral pattern that iterates through a data structure. An iterator traverses a data structure and gives access to the data structure s elements without revealing the data structure s internal representation. It also allows you to traverse a data structure in several ways without bloating the data structure s interface. An iterator has a next element method and often has a method to check if the end of the traversal has been reached. All of the traversal details can be hidden from the client so that one method call is all that is needed to get the next element. If the data structure is changed when using an iterator, only the iterator will have to be changed. The calling classes will not need to be modified. An iterator needs an iterator interface. Java already comes with two basic iterator interfaces that you can implement. They are called Iterator and Enumeration. Both are in the java.util package. Several data structures built into Java such as lists use one or both of these iterators. Listed below is the code from each of the iterators. public interface Iterator { public boolean hasnext(); public Object next(); public void remove(); public interface Enumeration { public boolean hasmoreelements(); public Object nextelement(); As you can see, both iterators have a method that checks if there are more elements, and both have a method that gets the next element. The Iterator interface, however, has one more method than the Enumeration interface. The remove() method removes that last received object from the data structure and can only be called once for each call to next(). If you need an iterator that provides more functionality than the basic iterators provided for you by Java, you can simply write your own. Perhaps you would like several types of traversals possible. An example is if you want to traverse a list from the bottom or from the top. As an example, we will create a simple iterator for a Vector based on Java s Iterator interface. Shown below is the VectorIterator class. Design Patterns and CodePro University of Manitoba Tutorial

329 import java.util.iterator; import java.util.vector; public class VectorIterator implements Iterator { private Vector v; private int current; private boolean removeenabled; public VectorIterator(Vector v) { this.v = v; current = 0; removeenabled = false; public boolean hasnext() { if (current >= v.size()) return false; else return true; public Object next() { Object result = null; if (hasnext()) { result = v.elementat(current); current++; removeenabled = true; return result; public void remove() { if (removeenabled) { v.removeelementat(--current); removeenabled = false; The VectorIterator class implements Java s Iterator interface, therefore it must have the methods hasnext(), next(), and remove(). One of the fields is a Vector, which is a reference to the Vector to be traversed. The field named current is the current position in the traversal. The removeenabled flag is to allow only one call to remove() for each call to next(). The hasnext() method checks the position in the traversal against the size of the Vector. If the traversal position has reached the end of the Vector, false is returned. The next() method first makes sure there are more elements left in the traversal by calling hasnext(). Then it increments the traversal position and returns the element. The remove() method decrements the traversal position and then deletes the most recently returned element from the Vector. Design Patterns and CodePro University of Manitoba Tutorial

330 To use the VectorIterator in your code, first create a Vector and then pass it to the constructor when instantiating a VectorIterator, as shown below. Vector v = new Vector(); //add some elements to the Vector here VectorIterator vi = new VectorIterator(v); Now you can iterate through the vector by calling the VectorIterator instance s next() method. Template Method: The template method design pattern is a behavioral pattern that extracts common elements of program flow and places them in a superclass. This is a simple pattern that is used all the time. The template method pattern is used when common elements are placed in a base class where subclasses are used to implement the elements that vary. The base class in the template method pattern is often abstract. It will have one or more methods that are either abstract or have a default implementation that can be overridden by the subclasses. For an example, we will use the template method pattern to create classes to calculate interest. Interest is calculated two ways, with simple interest or with compound interest. The formula for simple interest is A = P(1 + ni) and the formula for compound interest is A = P(1 + i/q) nq, where A is the total amount, P is the principal amount, n is the number of years, i is the interest rate, and q is the number of times interest is compounded per year. We will create an abstract base class called Interest that has a method getamount() that returns the total amount. The getamount() method returns the product of the principal and the rest of the formula which is calculated by the subclasses in the abstract method calcinterest(). The Interest base class is shown below. public abstract class Interest { private double principal; public Interest(double principal) { this.principal = principal; public double getamount() { return principal * calcinterest(); protected abstract double calcinterest(); Design Patterns and CodePro University of Manitoba Tutorial

331 To calculate the simple interest, we create a class SimpleInterest that extends Interest. public class SimpleInterest extends Interest { private int numyears; private double interestrate; public SimpleInterest (double principal, int numyears, double interestrate) { super(principal); this.numyears = numyears; this.interestrate = interestrate; protected double calcinterest() { return (1 + numyears * interestrate); To calculate the compound interest, we create a class CompoundInterest that extends Interest. public class CompoundInterest extends Interest { private int numyears; private double interestrate; private int compoundsperyear; public CompoundInterest (double principal, int numyears, double interestrate, int compoundsperyear) { super(principal); this.numyears = numyears; this.interestrate = interestrate; this.compoundsperyear = compoundsperyear; protected double calcinterest() { return Math.pow(1 + interestrate / compoundsperyear, numyears * compoundsperyear); Both classes above implement the calcinterest() method where they calculate the part of the formula that is unique to each kind of interest. As you can see, the template method design pattern is a fairly simple idea and you have probably used it often whether you knew it or not. Design Patterns and CodePro University of Manitoba Tutorial

332 Using CodePro to Create Design Patterns: Although you can learn all the details of the design patterns and then implement them when you need them, it is often easier to use a program to automatically generate the basic structure of the patterns for you. A suite of Java development tools called CodePro contains wizards for design patterns as well as numerous other development tools such as metrics and code analyzing. CodePro is a commercial plug-in for Eclipse. There are several versions of CodePro. CodePro is split up into three parts, Advisor, Agility, and Build, each of which can be purchased separately. The Studio version contains all three parts as well as some collaboration tools. CodePro Express contains limited features from all three parts of CodePro. CodePro Studio supports all of the 23 GoF design patterns as well as several other patterns. CodePro is made by Instantiations, Inc. Their website is Creating design patterns using CodePro is easy. Under the File menu, select New > Other. Select Java on the left side and Pattern on the right side. A window appears with all the design patterns that CodePro can make. Select the design pattern you wish to create and click on Next. One or more wizard pages will then appear allowing you to customize the selected pattern. You can also easily add your own design patterns to those that CodePro already supports. For more information on adding design patterns to CodePro, see the documentation at The documentation for CodePro at Instantiations website can be found at CodePro is well documented, so we will not look at it in depth in this tutorial. Each design pattern has its own page in the documentation describing the pattern as well as any wizard pages for the design pattern. The documentation pages for each pattern also have links to several websites that have information on the design pattern. CodePro Example: To show how easy it is to create the structure for a design pattern using CodePro, we will use CodePro to create the example we used in the template method section of this tutorial. First, select New > Other from the File menu. Select Java on the left and Pattern on the right. Below is shown the selection window. Design Patterns and CodePro University of Manitoba Tutorial

333 Clicking on Next brings you to the following window. Design Patterns and CodePro University of Manitoba Tutorial

334 Select Template Method from the list and click Next. In the first page of the Template Method wizard, set the Abstract template to Interest, set Template method to getamount, and then add a Primitive operation by clicking on the Add button. To change the Return Type and Name columns in the Primitive operations table, simply click on the cell you wish to modify and then modify it. Change the name of the primitive operation you added to calcinterest and change its return type to a double. Click Next to get the next Template Method wizard page which is shown below. Design Patterns and CodePro University of Manitoba Tutorial

CS 201 Software Development Methods Spring Tutorial #1. Eclipse

CS 201 Software Development Methods Spring Tutorial #1. Eclipse CS 201 Software Development Methods Spring 2005 Tutorial #1 Eclipse Written by Matthew Spear and Joseph Calandrino Edited by Christopher Milner and Benjamin Taitelbaum ECLIPSE 3.0 DEVELOPING A SIMPLE PROGRAM

More information

David Scuse Department of Computer Science University of Manitoba. Eclipse 3.1

David Scuse Department of Computer Science University of Manitoba. Eclipse 3.1 David Scuse Department of Computer Science University of Manitoba Eclipse 3.1 Eclipse 3.1 1 ECLIPSE 3.1... 1 1.1 INTRODUCTION...1 1.2 INTERACTIVE DEVELOPMENT ENVIRONMENTS...1 1.3 THE ECLIPSE IDE...1 1.4

More information

Getting Started with Eclipse/Java

Getting Started with Eclipse/Java Getting Started with Eclipse/Java Overview The Java programming language is based on the Java Virtual Machine. This is a piece of software that Java source code is run through to produce executables. The

More information

ICOM 4015 Advanced Programming Laboratory. Chapter 1 Introduction to Eclipse, Java and JUnit

ICOM 4015 Advanced Programming Laboratory. Chapter 1 Introduction to Eclipse, Java and JUnit ICOM 4015 Advanced Programming Laboratory Chapter 1 Introduction to Eclipse, Java and JUnit University of Puerto Rico Electrical and Computer Engineering Department by Juan E. Surís 1 Introduction This

More information

Just Enough Eclipse What is Eclipse(TM)? Why is it important? What is this tutorial about?

Just Enough Eclipse What is Eclipse(TM)? Why is it important? What is this tutorial about? Just Enough Eclipse What is Eclipse(TM)? Eclipse is a kind of universal tool platform that provides a feature-rich development environment. It is particularly useful for providing the developer with an

More information

Code::Blocks Student Manual

Code::Blocks Student Manual Code::Blocks Student Manual Lawrence Goetz, Network Administrator Yedidyah Langsam, Professor and Theodore Raphan, Distinguished Professor Dept. of Computer and Information Science Brooklyn College of

More information

Code::Blocks Student Manual

Code::Blocks Student Manual Code::Blocks Student Manual Lawrence Goetz, Network Administrator Yedidyah Langsam, Professor and Theodore Raphan, Distinguished Professor Dept. of Computer and Information Science Brooklyn College of

More information

Getting Started (1.8.7) 9/2/2009

Getting Started (1.8.7) 9/2/2009 2 Getting Started For the examples in this section, Microsoft Windows and Java will be used. However, much of the information applies to other operating systems and supported languages for which you have

More information

Eclipse Tutorial. For Introduction to Java Programming By Y. Daniel Liang

Eclipse Tutorial. For Introduction to Java Programming By Y. Daniel Liang Eclipse Tutorial For Introduction to Java Programming By Y. Daniel Liang This supplement covers the following topics: Getting Started with Eclipse Choosing a Perspective Creating a Project Creating a Java

More information

Module Road Map. 7. Version Control with Subversion Introduction Terminology

Module Road Map. 7. Version Control with Subversion Introduction Terminology Module Road Map 1. Overview 2. Installing and Running 3. Building and Running Java Classes 4. Refactoring 5. Debugging 6. Testing with JUnit 7. Version Control with Subversion Introduction Terminology

More information

Installing the Amzi Prolog Plugin

Installing the Amzi Prolog Plugin 1, 2 by David Scuse, University of Manitoba, Winnipeg, Manitoba, Canada Last revised: October 27, 2003 Overview: In this tutorial, we describe the installation of Amzi Prolog (www.amzi.com) which now runs

More information

Slide 1 CS 170 Java Programming 1 Duration: 00:00:49 Advance mode: Auto

Slide 1 CS 170 Java Programming 1 Duration: 00:00:49 Advance mode: Auto CS 170 Java Programming 1 Eclipse@Home Downloading, Installing and Customizing Eclipse at Home Slide 1 CS 170 Java Programming 1 Eclipse@Home Duration: 00:00:49 What is Eclipse? A full-featured professional

More information

2 Getting Started. Getting Started (v1.8.6) 3/5/2007

2 Getting Started. Getting Started (v1.8.6) 3/5/2007 2 Getting Started Java will be used in the examples in this section; however, the information applies to all supported languages for which you have installed a compiler (e.g., Ada, C, C++, Java) unless

More information

SDKs - Eclipse. SENG 403, Tutorial 2

SDKs - Eclipse. SENG 403, Tutorial 2 SDKs - SENG 403, Tutorial 2 AGENDA - SDK Basics - - How to create Project - How to create a Class - Run Program - Debug Program SDK Basics Software Development Kit is a set of software development tools

More information

Getting Started with Eclipse for Java

Getting Started with Eclipse for Java Getting Started with Eclipse for Java Maria Litvin Phillips Academy, Andover, Massachusetts Gary Litvin Skylight Publishing 1. Introduction 2. Downloading and Installing Eclipse 3. Importing and Exporting

More information

CSCI 161: Introduction to Programming I Lab 1b: Hello, World (Eclipse, Java)

CSCI 161: Introduction to Programming I Lab 1b: Hello, World (Eclipse, Java) Goals - to learn how to compile and execute a Java program - to modify a program to enhance it Overview This activity will introduce you to the Java programming language. You will type in the Java program

More information

POOSL IDE Installation Manual

POOSL IDE Installation Manual Embedded Systems Innovation by TNO POOSL IDE Installation Manual Tool version 4.1.0 7 th November 2017 1 POOSL IDE Installation Manual 1 Installation... 4 1.1 Minimal system requirements... 4 1.2 Installing

More information

Introduction to Eclipse

Introduction to Eclipse Introduction to Eclipse In this chapter you install and configure Eclipse. I then use the classical HelloWorld example to show how to effectively create Java programs under Eclipse. I first discuss the

More information

RTMS - Software Setup

RTMS - Software Setup RTMS - Software Setup These instructions are for setting up the RTMS (Robot Tracking & Management System) software. This software will run on your PC/MAC and will be used for various labs in order to allow

More information

NetBeans Tutorial. For Introduction to Java Programming By Y. Daniel Liang. This tutorial applies to NetBeans 6, 7, or a higher version.

NetBeans Tutorial. For Introduction to Java Programming By Y. Daniel Liang. This tutorial applies to NetBeans 6, 7, or a higher version. NetBeans Tutorial For Introduction to Java Programming By Y. Daniel Liang This tutorial applies to NetBeans 6, 7, or a higher version. This supplement covers the following topics: Getting Started with

More information

Eclipse Environment Setup

Eclipse Environment Setup Eclipse Environment Setup Adapted from a document from Jeffrey Miller and the CS201 team by Shiyuan Sheng. Introduction This lab document will go over the steps to install and set up Eclipse, which is

More information

COMP 110/401 APPENDIX: INSTALLING AND USING ECLIPSE. Instructor: Prasun Dewan (FB 150,

COMP 110/401 APPENDIX: INSTALLING AND USING ECLIPSE. Instructor: Prasun Dewan (FB 150, COMP 110/401 APPENDIX: INSTALLING AND USING ECLIPSE Instructor: Prasun Dewan (FB 150, dewan@unc.edu) SCOPE: BASICS AND BEYOND Basic use: CS 1 Beyond basic use: CS2 2 DOWNLOAD FROM WWW.ECLIPSE.ORG Get the

More information

i2b2 Workbench Developer s Guide: Eclipse Neon & i2b2 Source Code

i2b2 Workbench Developer s Guide: Eclipse Neon & i2b2 Source Code i2b2 Workbench Developer s Guide: Eclipse Neon & i2b2 Source Code About this guide Informatics for Integrating Biology and the Bedside (i2b2) began as one of the sponsored initiatives of the NIH Roadmap

More information

CSCI 201 Lab 1 Environment Setup

CSCI 201 Lab 1 Environment Setup CSCI 201 Lab 1 Environment Setup "The journey of a thousand miles begins with one step." - Lao Tzu Introduction This lab document will go over the steps to install and set up Eclipse, which is a Java integrated

More information

The NetBeans IDE is a big file --- a minimum of around 30 MB. After you have downloaded the file, simply execute the file to install the software.

The NetBeans IDE is a big file --- a minimum of around 30 MB. After you have downloaded the file, simply execute the file to install the software. Introduction to Netbeans This document is a brief introduction to writing and compiling a program using the NetBeans Integrated Development Environment (IDE). An IDE is a program that automates and makes

More information

3 CREATING YOUR FIRST JAVA APPLICATION (USING WINDOWS)

3 CREATING YOUR FIRST JAVA APPLICATION (USING WINDOWS) GETTING STARTED: YOUR FIRST JAVA APPLICATION 15 3 CREATING YOUR FIRST JAVA APPLICATION (USING WINDOWS) GETTING STARTED: YOUR FIRST JAVA APPLICATION Checklist: The most recent version of Java SE Development

More information

Getting Started with Eclipse for Java

Getting Started with Eclipse for Java Getting Started with Eclipse for Java Maria Litvin Phillips Academy, Andover, Massachusetts Gary Litvin Skylight Publishing 1. Introduction 2. Downloading and Installing Eclipse 3. Importing and Exporting

More information

Eclipse Setup. Opening Eclipse. Setting Up Eclipse for CS15

Eclipse Setup. Opening Eclipse. Setting Up Eclipse for CS15 Opening Eclipse Eclipse Setup Type eclipse.photon & into your terminal. (Don t open eclipse through a GUI - it may open a different version.) You will be asked where you want your workspace directory by

More information

Module 3: Working with C/C++

Module 3: Working with C/C++ Module 3: Working with C/C++ Objective Learn basic Eclipse concepts: Perspectives, Views, Learn how to use Eclipse to manage a remote project Learn how to use Eclipse to develop C programs Learn how to

More information

Prerequisites for Eclipse

Prerequisites for Eclipse Prerequisites for Eclipse 1 To use Eclipse you must have an installed version of the Java Runtime Environment (JRE). The latest version is available from java.com/en/download/manual.jsp Since Eclipse includes

More information

Introduction to Eclipse

Introduction to Eclipse Introduction to Eclipse Ed Gehringer Using (with permission) slides developed by Dwight Deugo (dwight@espirity.com) Nesa Matic (nesa@espirity.com( nesa@espirity.com) Sreekanth Konireddygari (IBM Corp.)

More information

Hadoop Tutorial. General Instructions

Hadoop Tutorial. General Instructions CS246H: Mining Massive Datasets Hadoop Lab Winter 2018 Hadoop Tutorial General Instructions The purpose of this tutorial is to get you started with Hadoop. Completing the tutorial is optional. Here you

More information

Packaging Your Program into a Distributable JAR File

Packaging Your Program into a Distributable JAR File Colin Kincaid Handout #5 CS 106A August 8, 2018 Packaging Your Program into a Distributable JAR File Based on a handout by Eric Roberts and Brandon Burr Now that you ve written all these wonderful programs,

More information

- 1 - Handout #33 March 14, 2014 JAR Files. CS106A Winter

- 1 - Handout #33 March 14, 2014 JAR Files. CS106A Winter CS106A Winter 2013-2014 Handout #33 March 14, 2014 JAR Files Handout by Eric Roberts, Mehran Sahami, and Brandon Burr Now that you ve written all these wonderful programs, wouldn t it be great if you could

More information

At the shell prompt, enter idlde

At the shell prompt, enter idlde IDL Workbench Quick Reference The IDL Workbench is IDL s graphical user interface and integrated development environment. The IDL Workbench is based on the Eclipse framework; if you are already familiar

More information

Javac and Eclipse tutorial

Javac and Eclipse tutorial Javac and Eclipse tutorial Author: Balázs Simon, BME IIT, 2013. Contents 1 Introduction... 2 2 JRE and JDK... 2 3 Java and Javac... 2 4 Environment variables... 3 4.1 Setting the environment variables

More information

EMC Documentum Composer

EMC Documentum Composer EMC Documentum Composer Version 6.5 SP2 User Guide P/N 300-009-462 A01 EMC Corporation Corporate Headquarters: Hopkinton, MA 01748-9103 1-508-435-1000 www.emc.com Copyright 2008 2009 EMC Corporation. All

More information

NetBeans IDE Java Quick Start Tutorial

NetBeans IDE Java Quick Start Tutorial NetBeans IDE Java Quick Start Tutorial Welcome to NetBeans IDE! This tutorial provides a very simple and quick introduction to the NetBeans IDE workflow by walking you through the creation of a simple

More information

Running Java Programs

Running Java Programs Running Java Programs Written by: Keith Fenske, http://www.psc-consulting.ca/fenske/ First version: Thursday, 10 January 2008 Document revised: Saturday, 13 February 2010 Copyright 2008, 2010 by Keith

More information

PART 1. Eclipse IDE Tutorial. 1. What is Eclipse? Eclipse Java IDE

PART 1. Eclipse IDE Tutorial. 1. What is Eclipse? Eclipse Java IDE PART 1 Eclipse IDE Tutorial Eclipse Java IDE This tutorial describes the usage of Eclipse as a Java IDE. It describes the installation of Eclipse, the creation of Java programs and tips for using Eclipse.

More information

HOW TO USE CODE::BLOCKS IDE FOR COMPUTER PROGRAMMING LABORATORY SESSIONS

HOW TO USE CODE::BLOCKS IDE FOR COMPUTER PROGRAMMING LABORATORY SESSIONS HOW TO USE CODE::BLOCKS IDE FOR COMPUTER PROGRAMMING LABORATORY SESSIONS INTRODUCTION A program written in a computer language, such as C/C++, is turned into executable using special translator software.

More information

Your password is: firstpw

Your password is: firstpw SHARE Session #9777: WebSphere and Rational Developer Hands-on-Labs Building Java application on System z with RDz Lab exercise (estimate duration) Part 1: Your first Java application on z/os (~35 min).

More information

Sun ONE Integrated Development Environment

Sun ONE Integrated Development Environment DiveIntoSunONE.fm Page 197 Tuesday, September 24, 2002 8:49 AM 5 Sun ONE Integrated Development Environment Objectives To be able to use Sun ONE to create, compile and execute Java applications and applets.

More information

with TestComplete 12 Desktop, Web, and Mobile Testing Tutorials

with TestComplete 12 Desktop, Web, and Mobile Testing Tutorials with TestComplete 12 Desktop, Web, and Mobile Testing Tutorials 2 About the Tutorial With TestComplete, you can test applications of three major types: desktop, web and mobile: Desktop applications - these

More information

Introduction to Computation and Problem Solving

Introduction to Computation and Problem Solving Class 3: The Eclipse IDE Introduction to Computation and Problem Solving Prof. Steven R. Lerman and Dr. V. Judson Harward What is an IDE? An integrated development environment (IDE) is an environment in

More information

EMC Documentum Composer

EMC Documentum Composer EMC Documentum Composer Version 6.0 SP1.5 User Guide P/N 300 005 253 A02 EMC Corporation Corporate Headquarters: Hopkinton, MA 01748 9103 1 508 435 1000 www.emc.com Copyright 2008 EMC Corporation. All

More information

Laboratory 1: Eclipse and Karel the Robot

Laboratory 1: Eclipse and Karel the Robot Math 121: Introduction to Computing Handout #2 Laboratory 1: Eclipse and Karel the Robot Your first laboratory task is to use the Eclipse IDE framework ( integrated development environment, and the d also

More information

Drools Tools Reference Guide. Version: CR1

Drools Tools Reference Guide. Version: CR1 Drools Tools Reference Guide Version: 5.0.0.CR1 1. Introduction... 1 1.1. What is Drools?... 1 1.2. Drools Tools Key Features... 1 1.3. Other relevant resources on the topic... 2 2. Creating a New Drools

More information

Table of Contents. 1 Introduction Downloads Eclipse SDK Installation Eclipse Workspace Eclipse Preferences...

Table of Contents. 1 Introduction Downloads Eclipse SDK Installation Eclipse Workspace Eclipse Preferences... SDK Quickstar t S et Eclpse f or u Dig Pl ug - in De velo p me nt Table of Contents 1 Introduction... 3 2 Downloads... 4 3 Eclipse SDK Installation... 5 4 Eclipse Workspace... 7 5 Eclipse Preferences...

More information

egui Eclipse User Guide

egui Eclipse User Guide Imperas Software Limited Imperas Buildings, North Weston, Thame, Oxfordshire, OX9 2HA, UK docs@imperascom Author: Imperas Software Limited Version: 211 Filename: egui_eclipse_user_guidedoc Project: Imperas

More information

Laboratory Assignment #4 Debugging in Eclipse CDT 1

Laboratory Assignment #4 Debugging in Eclipse CDT 1 Lab 4 (10 points) November 20, 2013 CS-2301, System Programming for Non-majors, B-term 2013 Objective Laboratory Assignment #4 Debugging in Eclipse CDT 1 Due: at 11:59 pm on the day of your lab session

More information

Optional Eclipse Workspace Configurations

Optional Eclipse Workspace Configurations 2019/01/08 11:20 1/16 This page will instruct you to install and configure Eclipse as your MidiBox Integrated Development Environment (IDE). Eclipse is supported on multiple platforms, including Windows,

More information

In this lab, you will build and execute a simple message flow. A message flow is like a program but is developed using a visual paradigm.

In this lab, you will build and execute a simple message flow. A message flow is like a program but is developed using a visual paradigm. Lab 1 Getting Started 1.1 Building and Executing a Simple Message Flow In this lab, you will build and execute a simple message flow. A message flow is like a program but is developed using a visual paradigm.

More information

1.00 Lecture 2. What s an IDE?

1.00 Lecture 2. What s an IDE? 1.00 Lecture 2 Interactive Development Environment: Eclipse Reading for next time: Big Java: sections 3.1-3.9 (Pretend the method is main() in each example) What s an IDE? An integrated development environment

More information

CS520 Setting Up the Programming Environment for Windows Suresh Kalathur. For Windows users, download the Java8 SDK as shown below.

CS520 Setting Up the Programming Environment for Windows Suresh Kalathur. For Windows users, download the Java8 SDK as shown below. CS520 Setting Up the Programming Environment for Windows Suresh Kalathur 1. Java8 SDK Java8 SDK (Windows Users) For Windows users, download the Java8 SDK as shown below. The Java Development Kit (JDK)

More information

What s NetBeans? Like Eclipse:

What s NetBeans? Like Eclipse: What s NetBeans? Like Eclipse: It is a free software / open source platform-independent software framework for delivering what the project calls "richclient applications" It is an Integrated Development

More information

S D K Q U I C K S T A R T

S D K Q U I C K S T A R T S D K Q U I C K S T A R T S e t u p a n E c l i p s e E n v i r o n m e n t f o r u D i g P l u g - i n D e v e l o p m e n t 2 7 J u n e 2 0 0 8 TABLE OF CONTENTS 1 Goals...3 2 Downloads...4 3 Eclipse

More information

GETTING STARTED WITH THE ADOBE INDESIGN CS3 PLUG-IN EDITOR

GETTING STARTED WITH THE ADOBE INDESIGN CS3 PLUG-IN EDITOR GETTING STARTED WITH THE ADOBE INDESIGN CS3 PLUG-IN EDITOR 2007 Adobe Systems Incorporated. All rights reserved. Getting Started with the Adobe InDesign CS3 Plug-in Editor Technical note #10123 Adobe,

More information

The Road to CCSv4. Status Update

The Road to CCSv4. Status Update The Road to CCSv4 Status Update Code Composer Studio v4 Summary What is it? Major upgrade to CCS Major architectural changes Based on Eclipse open source software framework New registration/licensing/updating

More information

JDB - QUICK GUIDE JDB - INTRODUCTION

JDB - QUICK GUIDE JDB - INTRODUCTION http://www.tutorialspoint.com/jdb/jdb_quick_guide.htm JDB - QUICK GUIDE Copyright tutorialspoint.com JDB - INTRODUCTION Debugging is a technical procedure to find and remove bugs or defects in a program

More information

NSIGHT ECLIPSE EDITION

NSIGHT ECLIPSE EDITION NSIGHT ECLIPSE EDITION DG-06450-001 _v7.0 March 2015 Getting Started Guide TABLE OF CONTENTS Chapter 1. Introduction...1 1.1. About...1 Chapter 2. New and Noteworthy... 2 2.1. New in 7.0... 2 2.2. New

More information

Task-Oriented Solutions to Over 175 Common Problems. Covers. Eclipse 3.0. Eclipse CookbookTM. Steve Holzner

Task-Oriented Solutions to Over 175 Common Problems. Covers. Eclipse 3.0. Eclipse CookbookTM. Steve Holzner Task-Oriented Solutions to Over 175 Common Problems Covers Eclipse 3.0 Eclipse CookbookTM Steve Holzner Chapter CHAPTER 6 6 Using Eclipse in Teams 6.0 Introduction Professional developers frequently work

More information

A Quick Tour GETTING STARTED WHAT S IN THIS CHAPTER?

A Quick Tour GETTING STARTED WHAT S IN THIS CHAPTER? 1 A Quick Tour WHAT S IN THIS CHAPTER? Installing and getting started with Visual Studio 2012 Creating and running your fi rst application Debugging and deploying an application Ever since software has

More information

Basic Software Maintenance. Ham Station Ultra Software Package

Basic Software Maintenance. Ham Station Ultra Software Package 1 Carl Skip Glover, Jr. K1SPG Custom Software & Hardware Solutions 4 Valley of Industry Boscawen, NH 03303 (603) 369-7015 Email: pctech.skip@gmail.com Email: k1spg@arrl.net Basic Software Maintenance Ham

More information

Customizing DAZ Studio

Customizing DAZ Studio Customizing DAZ Studio This tutorial covers from the beginning customization options such as setting tabs to the more advanced options such as setting hot keys and altering the menu layout. Introduction:

More information

Java Program Structure and Eclipse. Overview. Eclipse Projects and Project Structure. COMP 210: Object-Oriented Programming Lecture Notes 1

Java Program Structure and Eclipse. Overview. Eclipse Projects and Project Structure. COMP 210: Object-Oriented Programming Lecture Notes 1 COMP 210: Object-Oriented Programming Lecture Notes 1 Java Program Structure and Eclipse Robert Utterback In these notes we talk about the basic structure of Java-based OOP programs and how to setup and

More information

BASIC USER TRAINING PROGRAM Module 5: Test Case Development

BASIC USER TRAINING PROGRAM Module 5: Test Case Development BASIC USER TRAINING PROGRAM Module 5: Test Case Development Objective Student will have an understanding of how to create, edit and execute a Test Case from Develop a Test Case Activity Page. Student will

More information

CSE 101 Introduction to Computers Development / Tutorial / Lab Environment Setup

CSE 101 Introduction to Computers Development / Tutorial / Lab Environment Setup CSE 101 Introduction to Computers Development / Tutorial / Lab Environment Setup Purpose: The purpose of this lab is to setup software that you will be using throughout the term for learning about Python

More information

QNX Software Development Platform 6.6. Quickstart Guide

QNX Software Development Platform 6.6. Quickstart Guide QNX Software Development Platform 6.6 QNX Software Development Platform 6.6 Quickstart Guide 2005 2014, QNX Software Systems Limited, a subsidiary of BlackBerry. All rights reserved. QNX Software Systems

More information

Software Installation Guide

Software Installation Guide Software Installation Guide Software Installation Guide 2024C Engagement Development Platform Developing Snap-ins using Java Page 1 of 11 Bring Your Own Device (BYOD) Requirements You will be using your

More information

Lab 0 Introduction to the MSP430F5529 Launchpad-based Lab Board and Code Composer Studio

Lab 0 Introduction to the MSP430F5529 Launchpad-based Lab Board and Code Composer Studio ECE2049 Embedded Computing in Engineering Design Lab 0 Introduction to the MSP430F5529 Launchpad-based Lab Board and Code Composer Studio In this lab, you will be introduced to the Code Composer Studio

More information

COBOL-IT Developer Studio Getting Started The Debugger Perspective Version 2.0

COBOL-IT Developer Studio Getting Started The Debugger Perspective Version 2.0 COBOL-IT Developer Studio Getting Started The Debugger Perspective Version 2.0 Page 1 ACKNOWLEDGMENT... 4 COBOL-IT DEVELOPER STUDIO TOPICS... 5 Introduction... 5 COBOL-IT Developer Studio License terms...

More information

Embarcadero PowerSQL 1.1 Evaluation Guide. Published: July 14, 2008

Embarcadero PowerSQL 1.1 Evaluation Guide. Published: July 14, 2008 Embarcadero PowerSQL 1.1 Evaluation Guide Published: July 14, 2008 Contents INTRODUCTION TO POWERSQL... 3 Product Benefits... 3 Product Benefits... 3 Product Benefits... 3 ABOUT THIS EVALUATION GUIDE...

More information

EUSurvey OSS Installation Guide

EUSurvey OSS Installation Guide Prerequisites... 2 Tools... 2 Java 7 SDK... 2 MySQL 5.6 DB and Client (Workbench)... 4 Tomcat 7... 8 Spring Tool Suite... 11 Knowledge... 12 Control System Services... 12 Prepare the Database... 14 Create

More information

NSIGHT ECLIPSE EDITION

NSIGHT ECLIPSE EDITION NSIGHT ECLIPSE EDITION DG-06450-001 _v5.0 October 2012 Getting Started Guide TABLE OF CONTENTS Chapter 1. Introduction...1 1.1 About...1 Chapter 2. Using... 2 2.1 Installing... 2 2.1.1 Installing CUDA

More information

Creating a new CDC policy using the Database Administration Console

Creating a new CDC policy using the Database Administration Console Creating a new CDC policy using the Database Administration Console When you start Progress Developer Studio for OpenEdge for the first time, you need to specify a workspace location. A workspace is a

More information

GNATbench for Eclipse User s Guide

GNATbench for Eclipse User s Guide GNATbench for Eclipse User s Guide Release 19.0.20180812.w AdaCore August 13, 2018 CONTENTS 1 Getting Started 1 1.1 Prior Required Tool Installations................................... 1 1.2 Conflicting

More information

Workstation Configuration

Workstation Configuration Workstation Configuration December 15, 2017 - Version 9.3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

More information

An Introduction to Eclipse: Quick Guide. Part 1: Getting Started with Eclipse Part 2: Working with Eclipse Useful Online Guides

An Introduction to Eclipse: Quick Guide. Part 1: Getting Started with Eclipse Part 2: Working with Eclipse Useful Online Guides An Introduction to Eclipse: Quick Guide Part 1: Getting Started with Eclipse Part 2: Working with Eclipse Useful Online Guides 1 1 Part 1: Getting Started with Eclipse Installation & Running The User Interface

More information

NSIGHT ECLIPSE EDITION

NSIGHT ECLIPSE EDITION NSIGHT ECLIPSE EDITION DG-06450-001 _v8.0 September 2016 Getting Started Guide TABLE OF CONTENTS Chapter 1. Introduction...1 1.1. About...1 Chapter 2. New and Noteworthy... 2 2.1. New in 7.5... 2 2.2.

More information

3. Hello World! for IDEA. Java. Summer 2008 Instructor: Dr. Masoud Yaghini

3. Hello World! for IDEA. Java. Summer 2008 Instructor: Dr. Masoud Yaghini 3. Java Summer 2008 Instructor: Dr. Masoud Yaghini Outline Java IDEs Creating A Project Making A Java Class Building the Project Running the Project References Java IDEs Java IDEs Integrated Development

More information

Getting the Most from Eclipse

Getting the Most from Eclipse Getting the Most from Eclipse Darin Swanson IBM Rational Portland, Oregon Darin_Swanson@us.ibm.com March 17, 2005 What is Eclipse An extensible tools platform Out-of-box function and quality to attract

More information

IBM ILOG OPL IDE Reference

IBM ILOG OPL IDE Reference IBM ILOG OPL V6.3 IBM ILOG OPL IDE Reference Copyright International Business Machines Corporation 1987, 2009 US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP

More information

Introduction. Key features and lab exercises to familiarize new users to the Visual environment

Introduction. Key features and lab exercises to familiarize new users to the Visual environment Introduction Key features and lab exercises to familiarize new users to the Visual environment January 1999 CONTENTS KEY FEATURES... 3 Statement Completion Options 3 Auto List Members 3 Auto Type Info

More information

Test/Debug Guide. Reference Pages. Test/Debug Guide. Site Map Index

Test/Debug Guide. Reference Pages. Test/Debug Guide. Site Map Index Site Map Index HomeInstallationStartAuthoringStreamSQLTest/DebugAPI GuideAdminAdaptersSamplesStudio GuideReferences Current Location: Home > Test/Debug Guide Test/Debug Guide The following topics explain

More information

Section 2: Developer tools and you. Alex Mariakakis (staff-wide)

Section 2: Developer tools and you. Alex Mariakakis (staff-wide) Section 2: Developer tools and you Alex Mariakakis cse331-staff@cs.washington.edu (staff-wide) What is an SSH client? Uses the secure shell protocol (SSH) to connect to a remote computer o Enables you

More information

Intro to MS Visual C++ Debugging

Intro to MS Visual C++ Debugging Intro to MS Visual C++ Debugging 1 Debugger Definition A program used to control the execution of another program for diagnostic purposes. Debugger Features / Operations Single-Stepping 100011101010101010

More information

Using Eclipse for Java. Using Eclipse for Java 1 / 1

Using Eclipse for Java. Using Eclipse for Java 1 / 1 Using Eclipse for Java Using Eclipse for Java 1 / 1 Using Eclipse IDE for Java Development Download the latest version of Eclipse (Eclipse for Java Developers or the Standard version) from the website:

More information

Function. Description

Function. Description Function Check In Get / Checkout Description Checking in a file uploads the file from the user s hard drive into the vault and creates a new file version with any changes to the file that have been saved.

More information

Index. Symbols. /**, symbol, 73 >> symbol, 21

Index. Symbols. /**, symbol, 73 >> symbol, 21 17_Carlson_Index_Ads.qxd 1/12/05 1:14 PM Page 281 Index Symbols /**, 73 @ symbol, 73 >> symbol, 21 A Add JARs option, 89 additem() method, 65 agile development, 14 team ownership, 225-226 Agile Manifesto,

More information

Using Eclipse Europa - A Tutorial

Using Eclipse Europa - A Tutorial Abstract Lars Vogel Version 0.7 Copyright 2007 Lars Vogel 26.10.2007 Eclipse is a powerful, extensible IDE for building general purpose applications. One of the main applications

More information

HOW TO BUILD YOUR FIRST ROBOT

HOW TO BUILD YOUR FIRST ROBOT Kofax Kapow TM HOW TO BUILD YOUR FIRST ROBOT INSTRUCTION GUIDE Table of Contents How to Make the Most of This Tutorial Series... 1 Part 1: Installing and Licensing Kofax Kapow... 2 Install the Software...

More information

What is Eclipse? A free copy can be downloaded at:

What is Eclipse? A free copy can be downloaded at: Using Eclipse What is Eclipse? The Eclipse Platform is an open source IDE (Integrated Development Environment), created by IBM for developing Java programs. Eclipse is now maintained by the Eclipse Foundation,

More information

Lab Exercise 1 Using EGit and JUnit

Lab Exercise 1 Using EGit and JUnit Lab Exercise 1 Using EGit and JUnit This lab exercise will get you familiar with following: EGit, an Eclipse plug-in to use to a distributed version control system called Git. JUnit, a unit testing framework

More information

The ImageJ Eclipse Howto

The ImageJ Eclipse Howto 13-10-2018 1/25 The ImageJ Eclipse Howto The ImageJ Eclipse Howto A guide on how to include ImageJ into Eclipse and develop plugins using this IDE. Author: Patrick Pirrotte (patrick@image-archive.org)

More information

Freescale Semiconductor Inc. Vybrid DS-5 Getting Started Guide Rev 1.0

Freescale Semiconductor Inc. Vybrid DS-5 Getting Started Guide Rev 1.0 Freescale Semiconductor Inc. Vybrid DS-5 Getting Started Guide Rev 1.0 1 Introduction... 3 2 Download DS-5 from www.arm.com/ds5... 3 3 Open DS-5 and configure the workspace... 3 4 Import the Projects into

More information

Debugging in AVR32 Studio

Debugging in AVR32 Studio Embedded Systems for Mechatronics 1, MF2042 Tutorial Debugging in AVR32 Studio version 2011 10 04 Debugging in AVR32 Studio Debugging is a very powerful tool if you want to have a deeper look into your

More information

1.00/1.001 HowTo: Install Eclipse

1.00/1.001 HowTo: Install Eclipse 1.00/1.001 HowTo: Install Eclipse Spring 2008 1.00/1.001 will use the Eclipse Integrated Development Environment (IDE) to create, compile, and run Java programming assignments. Eclipse version 3.3.1.1

More information

Before you start with this tutorial, you need to know basic Java programming.

Before you start with this tutorial, you need to know basic Java programming. JDB Tutorial 1 About the Tutorial The Java Debugger, commonly known as jdb, is a useful tool to detect bugs in Java programs. This is a brief tutorial that provides a basic overview of how to use this

More information

Eclipse CDT Tutorial. Eclipse CDT Homepage: Tutorial written by: James D Aniello

Eclipse CDT Tutorial. Eclipse CDT Homepage:  Tutorial written by: James D Aniello Eclipse CDT Tutorial Eclipse CDT Homepage: http://www.eclipse.org/cdt/ Tutorial written by: James D Aniello Hello and welcome to the Eclipse CDT Tutorial. This tutorial will teach you the basics of the

More information