In which we discover that Swing is not the only GUI game in town. In so doing we learn the rudiments of the Standard Widget Toolkit and we describe some of the key limitations of this alternative toolkit.
This chapter will introduce the basic classes of SWT, the Standard Widget Toolkit, which is an alternative GUI library developed mainly for the Eclipse Java IDE.[1] Development of Eclipse has been led primarily by IBM.[2]
The Standard Widget Toolkit is a complete GUI library for Java, completely independent of Swing and AWT. It is implemented as a library of native methods, so it cannot be ported to any Java runtime unless that platform has the native part of the SWT library implemented for it.
The first question one should ask, perhaps, is why create an alternative GUI? Good question. The answer, according to the SWT FAQ,[3] primarily has to do with execution speed and look-and-feel similarity to native GUI applications on each platform.
If we may editorialize, we find neither reason particularly compelling, although the execution speed argument made some sense when the Eclipse project started. Swing is unlikely to win any performance awards, even though each version brings some improvements in speed.[4] Still, these reasons do not seem particularly compelling for such a large duplication of effort and functionality.
Whatever the reason, SWT exists. SWT works by providing a thin abstraction layer over native GUI features. It is a small GUI library. It is implemented using the Java Native Interface, so it requires that a native binary library be implemented for your platform. Fortunately, such implementations exist for all platforms Eclipse runs on. So if you can run Eclipse, you can write and run SWT applications.
The next logical question is, “If you think SWT is unnecessary with Swing already there, why cover it in your book?” Also a sensible question. The answer is that there is very little published literature on this library (a notable exception being Chapter 10 of The Java Developer’s Guide to Eclipse by Shaver et al., from Addison-Wesley). Also, SWT provides the only fully functional GUI library that will work with the GNU Compiler for Java. As such, it is a major required component if you wish to write native compiled GUI applications on Linux systems.
Of course, there is another reason. Anyone heavily into Linux is well aware of the political and philosophical debate about Free Software and Open Source. If the core values of Free Software are critical for you, you should be aware that the IBM Common Public License[5] under which Eclipse (and thus SWT) are published is a Free Software license. You get the source code, you may use it in your own products, and it imposes obligations similar to the GNU GPL,[6] but goes even further by requiring you to grant royalty-free licenses for any patents you hold in derivative works.
So you might choose SWT (or not) for political or philosophical reasons. Both authors still suggest Swing first because it is the official Java GUI library. When an employer wants to know if you can write a Java GUI application, he or she almost certainly means a Swing application. Philosophy is great, but it may not put the food on your table. You need to know that Swing is not Free Software (and neither is either of the major Java SDKs), and SWT is Free Software, but it is up to you to decide what best serves your interests.[7]
How about portability? Well, it depends on what “portability” means to you. If portability means “looks and runs the same on all platforms,” then Swing offers better portability. If portability means “runs on all platforms for which there is a Java runtime,” then Swing offers better portability. If portability means “looks like a native application on all supported platforms,” then SWT is your choice. Make your selection accordingly.
The rest of this chapter will be devoted to describing the basic classes of SWT by converting one of the application classes from the previous chapter from Swing to SWT. We will not attempt to explain the operating principles of GUIs. For an introduction to GUI programming, see the previous chapter on Swing. It introduces the concepts and programming principles for GUI programming in Java. SWT is functionally similar, although quite spartan, providing only basic windows, controls, and events.
Eclipse also contains a family of higher level user interface classes, known collectively as JFace
, that provide UI features such as dialogs, wizards, font handlers, and images. We will not cover JFace
in this book.
SWT breaks some of the Java contract. For example, you cannot rely on garbage collection to clean up SWT objects. Any SWT object you create with new
must be explicitly destroyed with a call to the dispose()
method. Why? Since SWT is implemented with native methods, the low-level implementation allocates native OS data structures and objects that must be explicitly freed. Since the Java garbage collector cannot be relied upon to collect objects at a certain time (or ever, for that matter), these allocations can result in memory leaks and address space conflicts. As we shall see, however, SWT is well designed to minimize the amount of this that you need to worry about.
SWT is also close to the metal in the sense that it does not abstract the underlying message-based event system that drives both X Window and Microsoft Windows. If you have ever written an X Window or Microsoft Windows application in straight C (without a GUI framework library or class library), you have written a main()
function that contains an event loop. SWT actually puts simple method calls around this core message queue event loop. We’ll cover the details of this in the next section where we introduce the Display
and Shell
classes.
SWT consists mainly of classes that represent controls—such as buttons, text areas, scrollbars, and so on—and layout managers which are much like layout managers in Swing. But there are two other classes: Display
, which models the interface between your Java application and the underlying windowing system, and Shell
, which effectively represents a single window.
The application in Example 17.1 is a parallel to the simple Swing program in the last chapter (Example 16.1).
This simple program, like its parallel in the Swing chapter, is deceptive. Sure, this is a lot of code to say “Hello, world” but it is because what we are setting up here is an event-driven program that must respond to any valid user input.
One advantage of Swing that we haven’t pointed out up to now is that it is part of every Java runtime (well, not gcj; more on that later), so you have all the classes on your classpath without any special setup. Not so with SWT. The exact procedure for setting up to run an SWT application depends on what development environment you are using.
There is an excellent set of directions for running an SWT application under Eclipse in the SWT FAQ.[8] No matter what your environment is, there is a basic series of steps:
Download the Eclipse SDK.
Install it.
Extract the SWT JAR files.
Extract the SWT JNI files.
Configure your development environment.
Example 17.1. A simple SWT application
import org.eclipse.swt.*; import org.eclipse.swt.layout.*; import org.eclipse.swt.widgets.*; /** * @author mschwarz * * Sample SWT "Hello, world" application */ public class SWTHelloWorld { public static void main(String[] args) { Display disp = new Display(); Shell window = new Shell(disp); window.setLayout(new RowLayout()); Label label = new Label(window, SWT.NONE); label.setText("Hello, world."); window.setSize(320, 160); window.open(); while (!window.isDisposed()) { if (!disp.readAndDispatch()) { disp.sleep(); } } disp.dispose(); } }
Let’s go over these in a bit more detail.
SWT was developed as a GUI library for the Eclipse project. It is distributed as part of Eclipse. There is no official standalone SWT package. The right way to obtain SWT is to download and (at least temporarily) install the Eclipse SDK. See Section 10.4 for details.
If you have followed our sage advice and downloaded the GTK version of the Eclipse SDK, then you need to copy out the SWT JAR files. There are two files in the GTK version, and just one in the Motif version. The GTK version’s files are swt.jar
and swt-pi.jar
. They are both in the eclipse/plugins/org.eclipse.swt.gtk_2.1.2/ws/gtk
directory. You will need to have both of these JAR files on the classpath of any SWT application you are compiling or running.
Remember that SWT is a JNI library. You must also have the native Linux shared libraries. These need to be made available to the Java native loader. The files you need are located in the eclipse/plugins/org.eclipse.swt.gtk_2.1.2/os/linux/x86
directory. The .so
files there must be available to any running SWT application. There are a couple of ways to do this. First, as described in Section 5.7, you can set the LD_LIBRARY_PATH
environment variable. You also can use the -D
parameter for the runtime VM to set the java.library.path
property.
If you want to, you can copy these files out of the eclipse
directory to some other location and then erase the eclipse
directory with the lovable old standby, rm -rf eclipse
.
Oh, by the way, once you have compiled the sample code above and set your classpath and Java library path correctly, running the application produces the window shown in Figure 17.1.
Before we launch into this discussion, we should point out that the Javadoc documentation for all SWT packages is available as part of the Eclipse Platform documentation.[9] You might want to use that resource along with this lightweight tutorial to fill in the gaps and shortcuts.
It should not be too surprising that there are similarities between SWT, AWT, and Swing. They all take different approaches to solving the same problem, namely how to control the complexity of a graphical event-driven application. Because the problem is the same, there can’t help but be similarities between different solutions. By now you may have deduced that the Shell
class is an analog to the JFrame
class, and that SWT uses a system of layout managers not too different from Swing. If so, you are on the right track and well on your way to using SWT.
If we had to summarize the difference in approaches between SWT and Swing, it would be that SWT tries to provide a small number of complex classes, and Swing tries to provide a large number of simpler classes. Obviously, this is a generalization, but everybody generalizes. Sorry.
The Display
is a class that provides the link to the underlying GUI system. Think of it as an abstraction of the interface to the windowing system. In almost all cases, an SWT application will have exactly one instance of Display
.
The Shell
class represents a window. This class descends from a series of abstract parent classes, so if you look at the Javadoc for Shell
and think it is simple, be sure to drill down into those parent classes! We’ll discuss Shell
quite a bit more as we go along.
The conversion of an existing application is a complex process. Always consider rewriting from scratch. Still, it is worthwhile to show an application converted from Swing to SWT, because it will emphasize the relationship between the two.
We begin with the reobjecting. Starting with the BudgetPro
class, we need to add an instance of the Display
class. Then the JFrame
becomes a Shell
. Likewise, the JLabel
s become Label
s. Then ... Wait a minute. You don’t need a blow-by-blow account. Maybe it would be simpler to show you what SWT classes roughly correspond to the equivalent Swing classes (Table 17.1).
Table 17.1. Major SWT widgets and their Swing equivalents
We are going to walk you through converting only one of the GUI source files for the BudgetPro application. We will leave converting the rest as an exercise for you. We’ll talk about some of the entertaining differences between the models. As you shall see, there is no clear “winner” here between SWT and Swing. Almost all technical choices—SWT versus Swing, Java versus C++, Emacs versus vi, or for that matter UNIX versus Windows—are tradeoffs. This is no exception. There are things we like about SWT. For simple GUI applications, we think it is easier to set up and use. We think it is easier to learn in its entirety than Swing. Swing, on the other hand, is more complete, offering classes that will do more than SWT. So the best solution depends (as always) on your requirements.
We are going to tackle converting BudgetPro.java
from Swing to SWT. In real life, this is an exercise you are unlikely to have to carry out. You will more likely write your GUI applications from scratch. But going through the conversion provides a useful roadmap for talking about the architecture of SWT; it teaches you SWT in terms of a class library with which you are already familiar.
First off, we change the packages imported at the start of the file. Remove all of the awt
and swing
packages. If you are using an IDE, this should flag every single line of code that touches the GUI as an error. This can be a big help when you are doing a mass conversion like this. When you have killed all the compile errors, you know you are well on your way to completing the conversion.
Replace the import
statements with the imports you are likely to need for your SWT application. These are:
import org.eclipse.swt.*; // The static SWT class, which contains a number of constants. import org.eclipse.swt.widgets.*; // The widgets library. Almost all your display elements are here. import org.eclipse.swt.events.*; // Event handlers import org.eclipse.swt.layout.*; // Layout managers
We will go into these families of classes in more detail as we convert the members and methods of BudgetPro.java
.
The next step is to convert the GUI members of the class from the Swing classes to their SWT counterparts. Of course, SWT requires the Display
class, which has no analog in SWT, so we add a Display
type member named disp
just ahead of the frame
member.
Next, we change the type of frame
from JFrame
to Shell
. We could rename the member,[10] but why add to our typing burden? The name is still clear and meaningful, even if it doesn’t match the SWT name.[11] There’s more to it than just changing the type, however. The constructor call for the JFrame
doesn’t match any constructor for Shell
. In fact, the Shell
constructor requires a Display
object argument, and all subsequent constructors for widgets and controls require a Composite
as an argument.
This is a key difference between Swing and SWT. Swing allows you to build GUI components in arbitrary order at arbitrary times and then join them up to the GUI with an add()
method call. SWT instead requires that you link your components up to the GUI element they belong to when they are constructed. There are good reasons for this difference. Remember that SWT allocates native objects and memory that Java’s garbage collector cannot recover. Because of this, SWT makes the promise that if you call the dispose()
method on any SWT object, it will dispose of it and everything it contains. That allows you to clean up all resources from an SWT program by calling dispose()
on the top level Display
object. If SWT allowed you to build GUI structures independently and then graft them onto the hierarchy, it could not keep this promise. For this reason (amongst others) SWT objects are always built in a fairly rigid top-down manner.[12]
The most direct consequence of this is that we have to get rid of the constructors on these declarations. We’ll start construction in the main()
. So, away with the constructors for the GUI elements. We now need to change the JButton
s to Button
s and the JLabel
s to Label
s. Again, if you are using a dynamic IDE, you should see your error count skyrocket with these changes (well, maybe not really skyrocket, since the import
changes have already produced a lot of errors right off the bat).
Finally, we remove the AbstractTableModel
member. SWT has a simpler (and more limited) table functionality that we will discuss later.
The main (pun unintended) changes that need to be made here include allocating the SWT Display
, changing from instantiating a JFrame
to a Shell
, doing away with the Swing “look and feel” stuff (an SWT application always looks like a platform-native application, that’s SWT’s main selling point), and reworking the construction of the GUI. We’ll explain that a little bit later.
For now, we take care of the simple changes. Remember that main()
is a static method, so we do not have any nonstatic class members available right now. The original BudgetPro
constructor took a JFrame
argument, now it will have to get a Display
and a Shell
. So we have to allocate a local Display
and a local Shell
. We also need to add the Display
argument to the BudgetPro
constructor.
After this is done, we modify the call to the constructor to pass the local Display
and Shell
to our class instance.
Next, we have to set a layout manager. The original application used the Swing BorderLayout
layout manager. SWT doesn’t have such a critter. Fortunately, the original used only the north, center, and south positions of the BorderLayout
. SWT has a simple layout manager called a FillLayout
that puts its contained controls in a single row or column, equally sized. Putting the three controls in a column will end up looking much like using the north, center, and south of a BorderLayout
. So we change the call to the frame.setLayout()
to pass in a new FillLayout
and add the SWT.VERTICAL
attribute.
The next block of code in main()
sets the Swing look and feel. SWT has nothing like this. All SWT applications look like native applications (we seem to be saying that a lot), so all of this code may be removed.
The next block of code calls methods on the application object (app
) that, in the original, construct the three “chunks” of UI and add them to the frame using the BorderLayout
attributes. Since, as we explained earlier, all SWT controls must be explicitly joined to a parent control when they are constructed, the separate create-then-add semantics used in the original will not apply. In the next section, we will walk through converting one of these three create methods. For now, it is enough to know that they will be changed to be methods that return void
(no return value) and the calls to add()
may be deleted.
That completes the conversion of main()
.
Lest you believe that this means the application is ready to run, just try compiling what you have. Got a few errors yet, don’t we?
Let’s walk through converting the createStatus()
method and its related methods. We’ll then briefly discuss converting the createList()
and createButtons()
concentrating on the details of the unique UI widgets used in each.
In BudgetPro, the top part of the UI is the status pane. It consists, basically, of three labels. In the original application, this pane is constructed by the createStatus()
method. In the original, it returns a Swing Component
, which is then placed by calling add()
on a container managed by the caller.
In SWT, Widget
s must be joined to their containers at construction, so we must restructure this code a little bit. We create a Group
to hold our classes together as a unit. We attach the group directly to the parent Shell
by using the member variable frame
. We set the layout manager to be RowLayout
.
We then populate the Group
. First, we add the Up button, which is only enabled when in a subaccount. While SWT does support image buttons, we take the shortcut of using the SWT.ARROW
style, bitwise-or’ed with the SWT.UP
style. Next, we populate the group with our Label
s.
Note a change we will talk about some more below: The listener for the Button
object called upton
is changed. The method is renamed from addActionListener()
to addSelectionListener()
. Event handling in SWT is similar to Swing/AWT, but not identical, as we will see when we go over the rewrite of the actual event handler code a little later on.
These are the only changes we make to this method.
If a Composite
has no layout manager, each Widget
in the Composite
must have its size and position explicitly set, or else their sizes will default to zero, and they will all be invisible! Tremendous details on SWT layout manager classes can be found in the article ““Understanding Layouts in SWT”” by Carolyn MacLeod and Shantha Ramachandran on the Eclipse Web site.[13]
The setStatus()
method is called whenever the data in the core model changes. Its job is to update the UI to reflect those changes. More specifically, it updates the status pane at the top of the UI. There are corresponding methods for the list pane and the button pane.
Oddly, there are no changes in this particular method. The purpose of this method is unchanged. It updates the Label
s with the new numbers and checks to see if the current Account
is the top level Account
. If it is, the Up button is disabled, otherwise it is enabled.
It turns out that all of the methods called on the UI classes in this method have the same names and purposes in Swing and SWT. Don’t assume this will be true in the other cases.
Finally, in the litany of conversion, we have to modify the event handlers. In this case, the only event of interest is when the Up button is pressed. Pressing a Button
produces a Selection
event.
In SWT, there are several types of events. Generally, you specify a class that will handle the event by calling one of the add...Listener()
methods on the Widget
that you wish to process the event for. Examples of these method calls include:
There are others. SWT naming conventions define an interface for which each add...Listener()
method is named. For example, there is a SelectionListener
interface. Many such interfaces have multiple methods, each to handle a distinct kind of event; for example, the MouseListener
interface defines separate methods to handle a button down event, a button release event, and a double-click event. As in Swing, it is common to implement event listeners as anonymous inner classes that implement the listener interface. However, since it is common to be interested only in some (or even only one) listener event, it is annoying to have to implement the full interface, since you have to provide method implementations for every event. For this reason, SWT also provides classes called adapters that implement “do-nothing” methods for every listener event. These also follow a naming convention. For example, the adapter for the MouseListener
interface is a class named MouseAdapter
; the SelectionListener
interface has an adapter named SelectionAdapter
, and so on.
For us, this means that we are going to create a reference to an anonymous inner class that implements the SelectionListener
interface by extending the SelectionAdapter
class. This is probably the weirdest common code construct in Java. Let’s take a direct look at that method (Example 17.2).
If you can correctly answer the following question, then you can be reasonably assured that you do, in fact, understand what is going on here. Would the program compile and run correctly if the type of the upAction
variable were changed to SelectionAdapter
? The answer is in the footnote.[14]
Example 17.2. The upton Button
event listener class reference declaration
private SelectionListener upAction = new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { // this is the action for UP arrow icon; Account next; next = current.getParent(); if (next != null) { current = next; setStatus(); } } } ;
To keep this book to a reasonable size, we are always trying to avoid covering the same ground more than once. We won’t walk you through the details of converting the createList()
and createButtons()
methods as we did with the createStatus()
method, but we will talk about the details of converting to SWT of some of the classes used in those methods.
Without a doubt, the biggest change the BudgetPro
class requires in order to convert from Swing to SWT lies in the table pane of the UI. The Table
class is the root of tables in SWT. The TableColumn
class defines the names and headers of the columns. TableColumn
constructors must have a Table
as their first argument, followed, as usual, by a numeric style specification. The TableItem
class defines a row in the Table
. As with TableColumn
, the TableItem
constructor must have a Table
as its first argument, followed by a numeric style.
If you think about it, this is an extension of the same design philosophy that requires that all constructors name their parent Composite
. While Swing’s abstract table model permits a nice separation between the data and the presentation, implementing a similar system in SWT would violate its strict container semantics.
You will need to follow the basic rewrite process outlined above and you will have to squish the Swing abstract table model into the simpler SWT table model. This will be your biggest challenge. Go to it. It is a great way to learn. Of course, you can also just download the complete SWT application from the book Web site.[15]
Completing the conversion of the BudgetPro
class does not complete the conversion of the entire application. The AcctDialog
class must also be converted. Use the same techniques we described here to convert that class as well. (Or, again, just download the complete SWT application.)
Our overall impression is that SWT is more easily comprehended in its entirety than Swing. It may be easier to learn SWT first, since Swing’s core model is more complex but more powerful. But SWT and Swing weren’t developed in that order and Swing is still much more widely used.[16]
For many GUI applications, our feeling is that it may be faster to write in the SWT idiom. The problem lies in that SWT’s model has limitations that Swing’s does not. Notably, SWT GUI elements are in a single rigid tree structure. It is not possible to have a factory class that constructs a GUI element such as a dialog box which is passed up to the caller to be grafted into place on a GUI. Instead, the parent element must be passed in, so all GUI elements belong to the single tree from the moment they are created. Also, by introducing objects that cannot be garbage-collected, SWT brings into your application the possibility of a class of bugs that Java otherwise eliminates.
Moreover, while converting a Swing application helped give this chapter shape, we would, in general, prefer that an application be designed with its GUI toolkit in mind. You would likely make slightly different design decisions depending on which style of the GUI you choose.
Up to now, we have told you again and again that SWT will work with gcj. But no Linux distribution with which we are familiar provides SWT with gcj out of the box. So how do you get SWT to play nice with gcj? Unfortunately, you have a bit of work to do. Fortunately, the work is not particularly difficult.
Before we proceed, we must acknowledge those who have been there before. We, too, had heard about SWT’s usability with gcj but we had never bothered to try it because there was no documentation on how to do it. We first made the attempt thanks to a great IBM developerWorks article by Kirk Vogen entitled ““Create Native, Cross-Platform GUI Applications”.” Follow the URL[17] to the information that enabled us to write this chapter.[18]
SWT source code is included in the Eclipse SDK download. See Section 10.4 for details on where and how to download and install Eclipse. Once you have Eclipse, you need to get your mits on the SWT source code. What we will do is compile the SWT source into a shared object file that we can link to any gcj application.
We’re assuming that you’ve got gcj installed. We’re assuming that you’ve unzipped the Eclipse SDK. We’re assuming you’re still reading the book. We have to make that assumption. The first thing you need to do is to unzip the SWT source code. It is found in ECLIPSE_INSTALL/plugins/org.eclipse.platform.linux.gtk.source_2.1.2/src/org.eclipse.swt.gtk_2.1.2/ws/gtk
. If you are using (as we recommend) the GTK version of Eclipse,[19] there are two files in there: swtsrc.zip
and swt-pisrc.zip
.
Once you have these unzipped, you have to compile the code with gcj. There are two different patterns these files follow. Files that do not contain native methods are compiled with a command line that looks like this:
$ gcj -c SomeClass.java -o SomeClass.o
Files that do contain native methods are compiled with a command line that looks like this:
$ gcj -fjni -c SomeClass.java -o SomeClass.o
That said, it does no harm to compile a source file that has no native methods with the -fjni
flag. This gives us a quick and dirty way to make our library file.
$ find . -name "*.java" -exec gcj -fjni -c {} ; -print
Remember, you are in UNIX-land. Leverage your tools! In this case, the advantage of using find is that, should the SWT source change (classes added or removed), our “compile process” will handle it. Obviously, you can take this in more sophisticated directions with make or ant. But this will get the job done for us for now.
That will compile all of the SWT source.[20] Next, we want to assemble all of the object files produced into a shared object.
$ gcj -shared -o swt.so $(find . -name "*.o" -print)
Once again, we leverage our tools. This time, we use bash execution quotes around our find command to get all of the .o
filenames added to our gcj command that builds the shared library. For our final trick, we will compile our HelloWorld
class from the start of this chapter with gcj and our new SWT shared library:
$ gcj -classpath=~/eclipse/plugins/org.eclipse.swt/swt.jar: ~/eclipse/plugins/org.eclipse.swt/swt-pi.jar -c HelloWorld.java $ gcj -main=HelloWorld -o HelloWorld Hello.o swt.so $ export LD_LIBRARY_PATH=.:~/eclipse: ~/eclipse/plugins/org.eclipse.swt/ws/gtk $ ./HelloWorld
Et voilà! You have the HelloWorld application! Again. But now it is an executable binary. Enjoy.
Compared to Swing, SWT is a somewhat simpler GUI library. Unlike Swing, it is Free Software and Open Source. It provides a full GUI library for use with gcj. It is part of the Eclipse project. It uses native methods that require calls to dispose of allocated objects. It has a rigid hierarchy that requires that lower level GUI components be linked to their parents when they are constructed. This means there are some limitations on how applications may be constructed. SWT is much less commonly used than Swing. Swing is the lingua franca of Java GUIs. SWT is definitely worth knowing, but if you want your skills to be marketable, it is probably best to start with Swing.
We just scratched the surface of SWT Widget
s. There are a bunch we haven’t covered.
SWT was written to support the Eclipse IDE. Eclipse is at http://www.eclipse.org/.
An introduction to SWT can be found at the same site: http://www.eclipse.org/articles/Article-SWT-Design-1/SWT-Design-1.html.
Part 2 of the same article is at http://www.eclipse.org/articles/swt-design-2/swt-design-2.html.
The full list of Eclipse technical articles (including those on SWT) may be found at http://www.eclipse.org/articles/index.html.
A good introductory article can be found on the Developer.com
Web site: http://www.developer.com/java/other/article.php/3330861.
As always, consider using Google.com
to find additional information.
In dead-tree form, Chapter 10 of the book The Java Developer’s Guide to Eclipse by Sherry Shavor et al. (Addison-Wesley, ISBN 0-321-15964-0), also provides an introduction to SWT.
[4] The question of speed in Java is a rather tired argument. If maximum speed is a primary concern, Java is probably not your first choice of a development language. In our experience, speed is something everybody says they need, but more often than not other considerations such as development time and error rate are much more important. Java is fast enough for virtually all MIS applications, and that is the market Java is squarely aimed at. Our computers keep getting faster, disk drives and memory keep getting cheaper. The “resource” and “performance” arguments only apply to applications where experienced designers would already have chosen C or assembly language. Besides, with the JIT compilers in both Sun’s and IBM’s JDKs, a well-written Java application is often as fast or faster than some other compiled languages, at least on the second run of the code.
[7] A lot of people couldn’t care less about the Free versus non-Free issue, but I must say that many of my most interesting workplace discussions have arisen from this issue. It is the first issue in my career that has had programmers talking about the balance between their personal interests, their employers’ interests, and the public interest. Wherever you stand philosophically, I think it is good that programmers are thinking about the consequences of their work at all of these levels. I wish there were more pressure at all levels of business to consider and balance all of these interests.
[8] http://dev.eclipse.org/viewcvs/index.cgi/~checkout~/platform-swt-home/faq.html?rev=1.83content-type=text/html#standalone. Note that this link is to the current revision in CVS as of this writing. You should take a look at the parent page to see if there is a newer revision.
[9] http://download.eclipse.org/downloads/documentation/2.0/html/plugins/org.eclipse.platform.doc.isv/reference/api/
[10] If you are using Eclipse, this is easily done throughout your code with the Refactoring feature.
[11] All right, I’m being lazy. Write your own book if you don’t like it.
[12] In some ways, this greatly simplifies SWT programs, but at the cost of some reusability. With Swing, you could construct a panel or other GUI element and reuse it in many places. You can achieve the same thing in SWT by encapsulating such a construct in its own class and passing in a parent to the constructor, but this is a bit more bulky and complex than the Swing way.
[14] Yes, it would. The reason is that the addSelectionListener()
method takes an argument of type SelectionListener
. Both SelectionListener
and SelectionAdapter
are of that base type. Aren’t Objects
wonderful?
[16] A gut feel—not based on any real statistics.
[18] Please note that Kirk’s article provides links to additional documentation and to an ant buildfile that automates the steps we are going to teach you manually here. We certainly didn’t want to steal anything from Mr. Vogen (or from IBM—scary!), so we will instead direct you to the (copyrighted) IBM Web resources. The article is worth checking out. It can save you some time over our version of the process. It is up to you.
[19] Be aware: As helpful as Kirk Vogen’s article and files are, they are written to an old version of gcj and they assume you are using the Motif version of Eclipse. His scripts work only with the Motif version.
[20] When we did this with Eclipse 2.1 GTK and gcj version 3.2.2, we had one compile error where the return type of the org.eclipse.swt.custom.TableCursor.traverse()
method was void, whereas the Control.traverse()
method (from which TableCursor
inherits) was boolean. So we hacked it. We changed the return type of TableCursor.traverse()
to boolean
and had it return true
. We didn’t test to see if this was right! Use at your own peril!
3.141.199.122