The Java TM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search

Trail: Creating a GUI with JFC/Swing
Lesson: Converting to Swing

## How to Convert

> This section presents steps you can follow to convert a program to use the Swing components. Each step applies to all programs -- applications and applets, alike -- unless noted otherwise.

### Step 1: Save a copy of the original program.

> Copy all of the program's files, including the `.java` files and the `.class` files. You will need this copy for several reasons:
> - You'll need to refer to the source during the conversion process.
> - After conversion, you should run both versions of your program side by side to compare them.
> - After conversion, you can compare the source code of both versions to apply what you learned to other programs you need to convert.
> - Some of your program's users might not be willing or able to immediately update their VM to a version that supports the Swing classes. If you want to keep them as customers, you'll need to keep providing the old AWT-based program in the interim.

### Step 2: Remove all references to the `java.awt` package.

> This step puts the compiler to work for you. By removing all imports and other code that references the `java.awt` package, you make the compiler tell you each time you use a class from that package. It's OK to use some AWT classes -- layout managers, for example -- but your program should use no AWT components. Here are a couple of examples of what to delete:

> >     //import java.awt.*;      //temporarily remove this import

> > or

> >     //import java.awt.Button; //temporarily remove this import
> >     import java.awt.Color;    //it's OK to leave this in, since
> >                               //Color isn't a component
> >     ...
> >     /*java.awt.*/Frame = new /*java.awt.*/Frame(...);

> Without the references to `java.awt`, the compiler generates a "not found" error every place your program uses an AWT component. This makes it easier for you to find and replace AWT components with their Swing equivalents. In Step 9, you will add back the imports for the AWT classes that you really need.

### Step 3: If your program is an applet, remove the `java.applet.*` import statement (if present) and any references to `java.applet.Applet`.

> You don't need to refer to the old `Applet` class because your Swing applet will be a subclass of Swing's `JApplet` class (which is itself a subclass of `Applet`). If your program uses `AppletContext`, `AppletStub`, or `AudioClip`, then of course you'll need to import those classes from the `java.applet` package. Here's an example of what to do:

> >     //import java.applet.*;      //temporarily remove this import
> >     import java.applet.AppletContext;     //add this if necessary

### Step 4: Import the main Swing package.

> Add the following import statement to your program.

> >     import javax.swing.*;

> This imports all of the Swing components plus some of Swing's other classes. If you want, you can be more meticulous and add one import statement per Swing class you use.

### Step 5: Be aware of thread-safety issues!

> Before you go further, remind yourself of this important fact: Although AWT is thread-safe, Swing is not. You must take this into consideration when converting your programs.

> Most programs modify components in event-handling methods and painting methods, which are called from the event-dispatching thread. Modifying a component in those methods is safe. However, if your program modifies a component anywhere else -- such as in the main thread after the GUI is visible, or in code called by a thread you have created -- you must take explicit action to make it thread-safe.

> This tutorial contains two sections about Swing and threads. First, Threads and Swing provides conceptual coverage. Next, How to Use Threads contains practical information and examples.

### Step 6: Change each AWT component to its closest Swing equivalent.

> The table provided in our resources section, Swing Replacements for AWT Components, lists each AWT component and its closest Swing equivalent. Use it as a guide for choosing a replacement for each AWT component used in your program.

> In the best case, the AWT component and its Swing replacement are source-compatible, and a simple name change is all that's required. For example, to convert from an AWT button to a Swing button, you just change all occurrences of `Button` to `JButton` in your program. Here's an example:

> AWT Code: | `Button button = new Button("A Button"); button.addActionListener(this);`
> Swing Code: | `JButton button = new JButton("A Button"); button.addActionListener(this);`

> Some Swing components are not source-compatible with the AWT component they replace. So, for some AWT components, you have to rewrite some code when replacing them with Swing components. Conversion Resources has information to help you with conversions that require more than a simple name change.

> While looking at the Conversion Resources section, take notes on changes that you might want to make later to take advantage of Swing features. For example, you might want to put images in your buttons, or to share data models between two components. Before making optional changes, though, we recommend that you make the minimal changes necessary to convert your program to Swing. Once you've successfully run the Swing version of your program, you'll be better able to judge how optional changes might improve your program.

### Step 7: Change calls to the `add` and `setLayout` methods.

> In programs that use AWT components, you add components directly to frames, dialogs, and applets. Similarly, you set the layout manager directly on those containers. In contrast, when you use the Swing versions of those containers, you add components to (and set the layout manager on) something called a content pane. Here's an example of converting some simple, typical code:

> AWT Code: | `frame.add(panel, BorderLayout.CENTER);`
> Swing Code: | `frame.getContentPane().add(panel, BorderLayout.CENTER);`

> Here is a slightly more complex example:

> AWT Code: | `frame.setLayout(new FlowLayout()); frame.add(button); frame.add(label); frame.add(textField);`
> Swing Code: | `Container contentPane = frame.getContentPane(); contentPane.setLayout(new FlowLayout()); contentPane.add(button); contentPane.add(label); contentPane.add(textField);`

> Here is an example of converting an applet. Note that the default layout manager for a content pane is `BorderLayout` -- not the `FlowLayout` used by `Applet`.

> AWT Code: | `setLayout(new BorderLayout()); add(button, BorderLayout.NORTH); add(panel, BorderLayout.CENTER);`
> Swing Code: | `Container contentPane = getContentPane(); contentPane.add(button, BorderLayout.NORTH); contentPane.add(panel, BorderLayout.CENTER);`

> For more information about content panes, see Swing Components and the Containment Hierarchy. For more information about converting applets, refer to Converting Applets.

### Step 8: Move painting code out of the `paint` and `update` methods.

> For Swing components, custom painting code goes in the `paintComponent` method. Other ways to paint are using standard or custom icons (which generally are used to display pictures) and borders. If your component has painting code that draws the component's edge, you might well be able to replace that code with a border.

> If your program has a `Frame`, `Dialog`, or `Applet` subclass that implements `update` or `paint`, then you need to move the painting code into another component, entirely. The reason is that each of these containers is covered by a content pane, which hides any painting the container might do. Exactly which component the painting code should move to depends on the type of painting. If the container's painting can be performed by an icon, than the component can be a standard label with an icon. Otherwise, the component should generally be a `JPanel` subclass that either performs the painting in its `paintComponent` method or uses a border to do the painting. You then add the component to the frame, dialog, or applet's content pane, as described in Step 7.

> See Working with Graphics for details about painting.

### Step 9: Use the compiler to find any other needed changes.

> After you've modified the source code as indicated in the prevous steps, use the compiler to try to compile your program. You can find instructions in Compiling and Running Swing Programs. During this step, you are basically getting the compiler to help you identify any conversions you might have overlooked. Don't expect your program to compile the first time!

> The compiler can help you do the following:

> - Find each AWT component that you forgot to convert to its Swing equivalent. If you removed all of the `java.awt` import statements from your program as suggested in step 2, the compiler displays an error message like this for each AWT component remaining in your program:

>   >     TextEventDemo.java:23: Class Button not found
>   >     in type declaration.
>   >             Button button = new Button("Clear");
>   >             ^

> - Identify which AWT classes your program still needs. If you removed all of the `java.awt` import statements from your program, the compiler displays an error message like this for AWT classes you still need:

>   >     TextEventDemo.java:17: Class BorderLayout not found
>   >     in type declaration.
>   >             BorderLayout layout = new BorderLayout();
>   >             ^

>   The AWT classes you might still need in a Swing program are layout managers, graphics-related objects such as `Color` and `Point`, and other non-component classes. You can import them using one import statement each. Or, if you're sure that you've replaced all the AWT components with Swing components, import the entire `java.awt` package again.

> - Locate any source incompatibilities between the AWT component and its Swing replacement. These typically show up as compiler errors about undefined methods. For example, although AWT text components have an `addTextListener` method, Swing text components don't. The compiler generates an error message like the following one indicating that `JTextField` doesn't have such a method.

>   >     TextEventDemo.java:22: Method addTextListener(
>   >     TextEventDemo.MyTextListener) not found in class
>   >     javax.swing.JTextField.
>   >         textField.addTextListener(new MyTextListener("Text Field"));
>   >                                  ^

> - Remove uses of deprecated API. If the compiler issues a deprecation warning, recompile with the `-deprecation` flag to get details. You can find information about what deprecation means, as well as a list of alternatives to API deprecated in JDK 1.1, in Migrating to 1.1. Also, the API documentation for the deprecated class or method should have information about what to use instead.
> Fix all problems reported by the compiler until the program compiles.

### Step 10: Run the Swing program.

> Run the program, as described in Compiling and Running Swing Programs. If you forgot to modify any calls to `add` or `setLayout`, the runtime system displays a message like this:

> >     java.lang.Error: Do not use javax.swing.JFrame.add() use
> >      javax.swing.JFrame.getContentPane().add() instead
> >             at javax.swing.JFrame.createRootPaneException(JFrame.java:333)
> >             at javax.swing.JFrame.addImpl(JFrame.java:355)
> >             at java.awt.Container.add(Container.java:212)
> >             at AppletDemo.main(AppletDemo.java:121)

> Go back to the source, fix the offending occurrence of `add` or `setLayout`, then compile and run again.

### Step 11: Compare the Swing version to the AWT version, and make any improvements that Swing enables.

> Although you might want the AWT and Swing versions of your program to be similar, be open to improvements offered by Swing. One difference you'll probably notice is that, unless your copy of the JDK has a `swing.properties` file that specifies otherwise, your converted program uses a new look and feel: the Java Look & Feel. You can specify another look and feel if you like. For more information, see Choosing the Look and Feel.

> You might be able to improve your program's GUI by using features available only to Swing components or by using the Swing components that have no AWT equivalents. Components completely new to Swing include color choosers, editable combo boxes, progress bars, split panes, tabbed panes, tables, tool tips, and trees. Features available only to Swing components include borders, which are especially useful for panels, and icons, which you can add to many components such as labels and buttons. You might also be able to replace a component you wrote yourself with a standard or customized Swing component.

### Step 12: Clean up!

> Now is the time to clean up your code. If you hacked any code together to get around some of AWT's deficiencies or bugs, clean it up now! Go through the tutorial sections and examples that are relevant to your program, and make sure that you use Swing features correctly. Review your program's accessibility to make sure that your program does all it can to support assistive technologies.

| Start of Tutorial > Start of Trail > Start of Lesson | Search