الثلاثاء، 8 يوليو 2008

programming

Java Desktop Development

by Andrei Cioroianu
02/18/2004

Java is a great technology for servers, personal computers, and mobile devices. Java is successful on servers and mobile devices because these environments need Java's cross-platform support. The situation is different on personal computers, but this could change sooner than you might think. In this article, I analyze how Java can improve the desktop world and then present the three major Java GUI toolkits: AWT, Swing, and SWT. In the following articles, I'll develop a full Java desktop application.

Desktops and Java

Today, the top desktop platforms are Windows, Mac, and Linux. None of them is perfect. Windows dominates the desktop market and has a huge number of applications and developers, but is expensive and had many security holes. Linux has a secure foundation, is free open source software, but is harder to use than Windows. Macs are easy to use and isn't a target for hackers like Windows, but the Mac's hardware and software options are limited when compared to what is offered for Windows and Linux.

Companies and individuals choose their operating systems depending on many factors. Reducing costs and increasing security are top priorities, which leads some organizations to migrate from Windows to Linux. Usability features and support for existing applications are very important factors for many users, which means that Windows will continue to have the largest market share. The Mac has its loyal users, which has kept Apple alive. The increasing popularity of Linux on desktops and the success of Mac OS X create the diversity that Java needs in order to become important on desktops.

Cross-Platform Support

Java runs on all relevant operating systems, including Windows, the Mac, and Linux. Java is the right desktop development platform for any organization that wants to be able to migrate from one operating system to another without having to port existing applications. It might be easier to build .NET applications using Microsoft's visual tools, but this choice locks you into the Windows platform.

Many would like to replace Windows with Linux right now to avoid the problems caused by the worms that exploit the weaknesses of Microsoft's operating systems. Besides user acceptance, one of the big problems when migrating from Windows to Linux is the significant investment in Windows applications. If your applications are built in Java, you don't have these problems. Java GUIs can look the same on all operating systems or they can emulate the native look. No porting is needed.

One day, another desktop operating system could emerge. Java is a safe bet because it runs on Windows and Linux now and it will presumably run on these future operating systems. Using Java, we actually prepare the migration to the next generation of operating systems, which will be developed sooner or later by Microsoft, by the open source community, or by somebody else.

Rich Set of Features

Initially, Java had a very limited set of features for building graphical user interfaces (GUIs). The idea was to wrap the native GUI widgets of the various operating systems with a platform-independent Java API called Abstract Window Toolkit (AWT). Only common widgets such as text field, text area, check box, radio button, list, and push button were supported by AWT. The graphics and imaging features were also very limited. That was, at best, enough for building simple applets.

Recognizing the need for more advanced GUI components and graphic capabilities, Sun has developed Swing, Java 2D, Java 3D, Image I/O, Java Advanced Imaging (JAI), and many others. Some of these frameworks are now part of the Java 2 Standard Edition (J2SE) and the others are extensions that must be packed together with your application. Swing, Java 2D, and Image I/O, for example, are core Java APIs that come with the Java Development Kit (JDK) and Java Runtime Environment (JRE).

J2EE

Let's not forget about the J2EE platform. If you develop server-side applications and need a rich GUI, you should definitely choose Java. This allows you to move some of your code from the server side to the client side and vice versa. For example, a project could start with a web-based GUI. At some point, users might ask for a graphical feature that cannot be implemented in HTML. If you choose Java for the client application, you can reuse some of the code that was initially designed for the server side. Some of the classes will actually be shared by the server and client applications if you use Remote Method Invocation (RMI). Java desktop applications can also communicate with other Java and non-Java applications using web services, CORBA, TCP/IP, or HTTP.

Java GUI Toolkits

Java has three major GUI toolkits: AWT, Swing, and SWT. Swing is the standard API for building Java GUIs -- some of the AWT classes form the foundation of Swing. SWT is a new framework funded by IBM with a very promising future. Swing and SWT compete for the hearts and minds of the Java developers, but in fact they complement each other, since they address different requirements.

AWT

Abstract Window Toolkit (AWT) was designed for simple applets. It was not suitable for building rich desktop GUIs, but it introduced at least one good idea from the start: layout managers. Instead of using coordinates for defining the position of a component (button, text field, check box, etc.), you provide a hint to a layout manager, which is responsible for finding a place for the component. This mechanism was necessary because GUI components have different sizes on different operating systems.

In time, AWT was extended with a component model and event handling mechanism (defined by the JavaBeans specification), new graphics APIs (called Java 2D), support for clipboard and drag-and-drop operations, printing, accessibility, and a new GUI toolkit called Swing. All of these were grouped under an umbrella called Java Foundation Classes (JFC).

Swing

Swing is one of the most complex GUI frameworks ever developed. It has a complete set of GUI components ranging from buttons and text fields to tables, trees, and styled text editors. These components do not rely on the native widgets of the operating system; instead, Swing components are painted using graphic primitives such as lines, rectangles, and text. The painting is delegated to a look and feel (L&F) plug-in that can imitate the native L&F. Swing also has a platform-independent L&F called "Metal."

Swing's architecture was inspired by the Model-View-Controller (MVC) pattern. There is a clean separation between the GUI components and model objects that maintain the data that is viewed on screen. The communication between the GUI and data layers is based on events.

The initial release of Swing had many bugs and performance problems, which slowed its adoption. Swing's biggest problems have been addressed and many believe it is ready for building robust desktop applications. Today, there are many commercial products based on Swing, including most of the Integrated Development Environments (IDEs) for Java. My favorite IDE, JBuilder, uses Swing, and its speed is quite good.

SWT

Standard Widget Toolkit (SWT) is the GUI toolkit developed by IBM for its Eclipse IDE. SWT can be used outside of the Eclipse environment and offers direct access to the native GUI features of the operating system. Therefore, SWT-based Java applications have native GUIs and can be integrated with other native applications and components.

Suppose your desktop application generates HTML reports and you want to present them to the user. You can use Swing to view simple HTML documents, but this is not the ideal solution. It would be preferable to use the rendering engine of IE or Mozilla in your application. The SWT community is currently designing a browser API that will let you create HTML widgets based on IE or Mozilla.

SWT is currently running on AIX, HPUX, Linux, QNX, Solaris, and Windows. A port for Mac OS X is in the early access stage.

Misconceptions and Bugs

There are misconceptions surrounding Java/Swing, such as "Java/Swing is too slow," or "Java/Swing requires too much memory." Swing might be slow on an old Pentium with 32MB of RAM running JDK 1.2, but it's fast enough on a modest Pentium III with 256MB of RAM running JDK 1.4. It doesn't really matter if the application responds in one or 10 milliseconds to a mouse click; the user sees no difference. Java is good for enterprise servers accessed by hundreds or even thousands of concurrent users. Java is good for mobile devices with very limited resources. Why wouldn't Java be good for desktop computers that are just waiting for a mouse click most of the time?

In my opinion, Swing's bugs were a much bigger problem than its speed. For example, if you were using JDK 1.2, you couldn't type the characters %&'($#!q in a Swing table (called a JTable). These eight characters have the same codes as the arrow keys, Home, End, Pgup, and Pgdn. One of the classes used by JTable was calling KeyEvent.getCharCode() instead of KeyEvent.getKeyCode(). This bug was corrected by JDK 1.3.

You would probably have abandoned Swing, annoyed by the fact that you couldn't type q in a table if you were just starting to use Swing with JDK 1.2. If you were less lucky and you had to develop a Swing application with JTable, you would have spent a couple of hours searching Sun's bug database (called the "bug parade") for a solution. Not finding what you needed (remember that Swing was new at the time), you would have spent many more hours looking into Swing's source code and developing a workaround. After such an experience, few would use Swing in another project. Here is what your workaround would have looked like:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
 
public class WorkingTable extends JTable
{
  public static final boolean JDK12
    = System.getProperty("java.version").startsWith("1.2");
 
  public void processKeyEvent(KeyEvent e) {
    if (JDK12) {
      char ch = e.getKeyChar();
      if (e.getID() == KeyEvent.KEY_TYPED
          && ((33 <= ch && ch <= 40) || ch == 'q')) {
        int anchorRow =
          getSelectionModel().getAnchorSelectionIndex();
        int anchorColumn = getColumnModel()
          .getSelectionModel().getAnchorSelectionIndex();
        if (anchorRow != -1 && anchorColumn != -1) {
          if (!isEditing())
            editCellAt(anchorRow, anchorColumn);
          Component editorComp = getEditorComponent();
          if (isEditing() &&
              editorComp instanceof JTextField) {
            JTextField textField =
              (JTextField) editorComp;
            textField.setText(textField.getText() + ch);
            return;
          }
        }
      }
    }
    super.processKeyEvent(e);
  }
 
}

Unfortunately, Swing had many problems like the one described above. Some of these problems were hard to solve, requiring a lot of work. For example, Swing's Open File and Save File dialogs are based on a component called JFileChooser that was only partially implemented in JDK 1.2 and 1.3 (some of the features were always disabled, and creating a new directory was a challenge for the average user). I don't know why Sun needed a few years to finish the JFileChooser in JDK 1.4. Before JDK 1.4, you had two choices: use the bad JFileChooser or build you own file chooser. Borland had the resources to build a good Open File dialog for their JBuilder 4. Most developers, however, used the standard JFileChooser, causing lots of problems for their users.

There is one important thing to notice: it was possible to build workarounds like those described above because Swing's source code was available. Studying the Java source code also makes you a better programmer and allows you to understand the internal mechanisms that work behind the Java APIs. This is useful when developing your own custom GUI components.

Summary

Java was released as an Internet technology for running applets in web browsers, but it had the capabilities to run standalone desktop applications right from the start. Unfortunately, AWT didn't offer the required desktop features. Swing addressed this problem, but it was full of bugs. Today, Java has the features you need for building large desktop applications and the bugs were fixed. The unique Java advantage is the so-called "write once, run anywhere" -- the ability to run Java code on Windows, Linux, the Mac, and many other operating systems.