Swing is the name for the high level component toolkit. It extends upon the AWT, and AWT knowledge is directly used. If you are familiar with AWT programming, it will be easy to migrate to Swing.
First, let's take a look at the packages of the Swing distribution. This will give us a good idea of what components are where and when and how to use them.
Here is a list of the packages in Swing 1.0.1 distribution:
When the JDK 1.2 package is released, these will be moved to java.awt package instead of com.sun.java package, although com.sun.java will still be used for portable JFC classes on platforms that don't implement the JFC and could not otherwise load classes in the java package from outside of the classpath. Thus, there will be dual versions of the Swing classes, java.awt.swing for platforms having Swing, and com.sun.java.swing for those other platforms with JDK 1.1 but without Swing support. The package prefix was going to be java.swing, but this has been changed by JavaSoft in JDK 1.2 to be java.awt.swing.
Which package prefix to use depends at this time on the deployment target of the Swing application. For use with JDK 1.1 and Swing 1.0.1, use the com.sun.java prefix. The java.awt prefix is built into JDK 1.2 which is currently in beta testing. It is important to note that the current package distribution of Swing 1.0.1 and JDK 1.2 beta 3 are not the same. For example, Swing 1.0.1 has the beaninfo package which JDK 1.2 Swing does not. Neither of the libraries is completed, further revisions of each will be released. When completed, the two versions will have an identical API and be interchangeable.
For the rest of this document, the Swing packages will be referred to sans prefix.
The accessibility package allows the open examination of components. These classes are used by assistive technologies like readers for the blind or magnifiers for vision impaired people. Originally developed to satisfy government requirements for disabled persons, they also offer a flexible external interface to the workings of accessible components.
The swing package contains the classes that will be used most often by Swing developers. It contains the user interface components of Swing, as well as other supporting classes such as the look and feel manager and interfaces to define rendering components for some of the Swing components.
The swing.basic package contains an implementation of each of the lightweight components in the swing package. It is included as a default implementation of the Swing's "Pluggable Look and Feel."
The swing.beaninfo package contains one class, SwingBeanInfo. BeanInfo classes for many of the components in the swing package extend this class. This package is undocumented in the current release.
The swing.border package contains convenience methods for a variety of borders to be used in user interface design to visually group and separate components. The borders can be drawn on any component.
The swing.event package contains events for the components in the Swing package that aren't handled by events in java.awt.event. This includes events for Tree, Table, and Drag and Drop events, as well as expanded List events and HyperlinkEvents for the text package.
The swing.plaf package contains the classes to implement Swing's "Pluggable Look and Feel." Each class in the package can be implemented and then set as the default view of that component. This package is not documented in the latest release. These installed "Look and Feels" are provided with the Swing 1.0.1 release: basic, metal, motif, and windows.
The swing.preview package contains classes that are not frozen as part of the Swing 1.0 release. This includes the classes JColorChooser and JFileChooser. Classes in this package are liable to change in future release.
The swing.table package contains support classes for the JTable component. Classes in this package control the data and display formats of tables.
The swing.text package contains text display and format classes for text aware components. This includes features such as document format, selection, and style. The swing.text.html package contains a minimal HTML displayer, and swing.text.rtf has a minimal Rich Text Format editor component.
The swing.tree package contains support classes for the JTree components. These classes are used to create layouts and attributes of tree components.
The swing.undo package contains the classes and interfaces to implement an undo system within Java. By using the classes in this package, an application can enable a user to undo mistakes or other unwanted changes to a document, and redo these changes.
There are a number of packages within the core Java API that are used with Swing.
Swing and Model/View/Controller
One design feature of Swing that enables several features is the use of the Model/View/Controller architecture.
How this works is that one component of the object tracks the data and abstract state of the components, another object represents the visual representation, and the Controller object affects changes on the Model and View objects.
Swing components are data aware. What this means is that their data model and visual representation can be updated from changes in data.
Swing and Threads
There are some threading issues which come into effect when using Swing components. Generally single threaded applications will have no problems with threads. There are some issues with threading for rendering offscreen images or other multithreaded activity.
This thread performance mostly has to do with event dispatching. The SwingUtilities class has methods to enable threadsafe operation.
Because Swing is based on the lightweight component framework also introduced in Java 1.1, it does not use the java.awt.peer package except for at a low level the java.awt.peer.WindowPeer. This further removes Java windowing components from the underlying operating system.
The swing package itself contains most of the classes that are regularly used when designing a user interface with Swing.
There are these interfaces in the swing package: Action, BoundedRangeModel, ButtonModel, CellEditor, ComboBoxEditor, ComboBoxModel, DesktopManager, Icon, ListCellRenderer, ListModel, ListSelectionModel, Renderer, RootPaneContainer, ScrollPaneConstants, Scrollable, SingleSelectionModel, and SwingConstants, and WindowConstants.
There are these classes in the swing package: AbstractAction, AbstractButton, AbstractListModel, BorderFactory, Box, BoxLayout, ButtonGroup, CellRendererPane, DebugGraphics, DefaultBoundedRangeModel, DefaultButtonModel, DefaultCellEditor, DefaultCellRenderer, DefaultDesktopManager, DefaultFocusManager, DefaultListModel, DefaultListSelectionModel, DefaultSingleSelectionModel, FocusManager, GrayFilter, ImageIcon, JApplet, JButton, JCheckBox, JCheckBoxMenuItem, JColorChooser, JComboBox, JComponent, JDesktopPane, JDialog, JDirectoryPane, JEditorPane, JFileChooser, JFrame, JInternalFrame, JLabel, JLayeredPane, JList, JMenu, JMenuBar, JMenuItem, JOptionPane, JPanel, JPasswordField, JPopupMenu, JProgressBar, JRadioButton, JRadioButtonMenuItem, JRootPane, JScrollBar, JScrollPane, JSeparator, JSlider, JSplitPane, JTabbedPane, JTable, JTextArea, JTextField, JTextPane, JTextPaneBeanInfo, JToggleButton, JToolBar, JToolTip, JTree, JViewport, JWindow, KeyStroke, LookAndFeel, MenuSelectionManager, OverlayLayout, ProgressMonitor, ProgressMonitorInputStream, RepaintManager, ScrollPaneLayout, SizeRequirements, SwingUtilities, SyntheticImage, Timer, ToolTipManager, UIDefaults, UIManager, and ViewportLayout. That might seem like quite a few classes, and it is, but then these classes represent comprehensive GUI functionality.
Let's divide these classes into groups to better see how they work together.
The classes in the Swing package that begin with the letter "J" are the common lightweight components and some Swing framework components. Each of them extends from the JComponent class. Also, two classes from the swing.preview package extend JComponent, JColorChooser and JFileChooser, as does the JTextComponent from the swing.text package.
Each of the AWT components has a JFC analog. For example, java.awt.Button is to swing.JButton as java.awt.Frame is to swing.JFrame. Generally, these are used the same as AWT components, with some new features from being derived from JComponent.
The basic object of Swing visual components is JComponent. JComponent is an extension of the java.awt.Container class and thus inherits it's methods amd those of Component, Container's ancestor class.
JComponents and extensions of JComponent have a variety of features. Each JComponent has a "pluggable look and feel." This means you can change the default display format and visual representation of the component.
You can specify a JComponent to handle keystrokes. In this way, when the JComponent or one of it's descendents has the focus keyboard input can be processed.
Another thing about JComponents is that they can trigger and control application Action events, which can also be set programmatically.
There are some other features of JComponents such as ToolTips, Localization, and double buffering.
The ToolTips feature displays informational text when the mouse is over a component for a given amount of time. To use the ToolTip feature use the setToolTipText(String text) method. For more information see JToolTip below.
A given swing.border.Border can be set as the border of a JComponent using the setBorder(Border border) method.
JComponents also provide information to the Accessibility framework. JComponent does not implement the Accessible interface, but all descendents of JComponent within the swing package do.
JFrame is the top level windowing component with menu support. JFrame is the subclass of java.awt.Frame.
Components and JComponents are not added directly to JFrame. Instead, they are added to the ContentPane. For, example, when adding a JButton to a JFrame,
JFrame jframe=new JFrame();
The content pane will not be null. Setting it to null will cause an exception. The content pane has a default BorderLayout layout manager.
JFrame also has methods to get and set the JRootPane, GlassPane, and JLayeredPane attributes of the JFrame.
The GlassPane is not a separate component, but rather a component that can be visualized as covering the JFrame and intercepting all events to the JFrame. The JLayeredPane is a lightweight container with a third dimension Z-order to regulate overlapping and stacked components.
JWindow is a top level window, similar to JFrame except for lack of JMenu accesor and mutator methods.
The JWindow constructor takes a JFrame as an argument. The JFrame does not have to be visible when the JWindow is created.
So, for example, a JWindow could be created with a code snippet like this:
JFrame frame=new JFrame("blank");
JWindow window=new JWindow(frame);
Similar to JFrame, components are not added directly to the JWindow but rather to it's ContentPane, and methods exist to get and set JRootPane, JLayeredPane, and the GlassPane.
The JRootPane class is a JComponent that can be derived from JFrame or JWindow from a call to getRootPane(). The JRootPane has methods to get and set the layout of the JRootPane, as well as getting and setting the GlassPane and JLayeredPane.
A JLayeredPane is a construct to manage multiple layers of display. When components are added to a JLayeredPane, the add method can take an argument to set which level of display to use for the added component. Alternatively, the layer can be set with a call to the setLayer() method.
Using the JLayeredPane, child components can thus be layered in front of or behind each other. The layer attribute represents the Z-order of the components' rendering, with higher values displayed in front of components added with lower layer attributes.
JDesktopPane is used with JInternalFrames in the creation of MDI (Multiple Document Interface) applications.
JDesktopPane extends JLayeredPane, and thus provides support for multiply layered JInternalFrames. In this way, a given child window of the MDI can be set to always display above the other JInternalFrame children as a control bar or menu interface.
The JDesktopPane is closely linked with the DesktopManager class, which provides implementation of the JDesktopPane's "Look and Feel" and implements actions that are taken on JInternalFrames.
JInternalFrames are the child components created and used with MDI. It has many of the same features of JFrame, including the fact the components are not added directly to it, but rather to it's content pane.
JInternalFrames are created and added to a given JDesktopPane at a given Z-order layer. In this way new JInternalFrames can be added to occlude or fall behind other JInternalFrames and content of the JDesktopPane. For example, to create a minimal JInternalFrame at a JDesktopPane's default layer would be something like this:
JDesktopPane jdesktoppane=new JDesktopPane();
JInternalFrame jinternalframe=new JInternalFrame("child frame");
JApplet is an extension of java.applet.Applet that is used with JComponents. It has a JRootPane, and so children added to a JApplet are added to the content pane and not directly to the JApplet, and other JRootPane methods are available as well.
Another feature of JApplet not available from Applet is that it can have set a JMenuBar similarly to JFrame. In this way, a JApplet can have a built-in menu.
The JDialog class provides a convenience for creating modal and non-modal dialogs. JDialogs have a JRootPane, so similarly to JFrame or JWindow components are added to the content pane, not directly to the JDialog.
The JDialog also has a method to set it's windowClosing behavior, based on the WindowConstants class which has three static variables: DISPOSE_ON_CLOSE, DO_NOTHING_ON_CLOSE, and HIDE_ON_CLOSE. On windowClosing, the default close operation is done and then any registered WindowListeners are also notified.
JOptionPane is a modal dialog class which has several convenience methods to acquire commonly requested data from the user for any JComponent.
It has a variety of static methods to display a JOptionPane given a parent component, the message to display, and the input type to receive. Each of these methods also has an internal variation for display from JInternalFrames which have similar semantics and usage to the methods that display JOptionPanes for regular JComponents.
The JScrollPane is a container to track a JViewport, scrollbars, and some options. It is a generic component to be used when a given user interface component will be too large or is of indeterminate size.
The JSplitPane is a container for two components. The division between the components is managed by the JSplitPane, so that adjustments to the divisor of the JSplitPane will alter the layouts of it's two child components. The JSplitPane's orientation can be either horizontal or vertical, separating the components along that axis.
The JTabbedPane is a container similar in some respects to a Container with a CardLayout, as well as tabs to display an identifier of each card. When a tab is clicked then it's associated component is brought to the front of the JTabbedPane display.
Tabs are added by one of the addTab() methods. Each of these methods designates a component and tab label to add to the JTabbedPane, with options to add an Icon to the label and set the tab's tooltip text.
JLabels are static components for the display of text strings, icons, or both.
The relative positioning of icons and strings within the JLabel can be set to the positional constants of the SwingContants class.
JPanels are generic lightweight containers. When migrating from AWT, use JPanel instead of Canvas.
The JButton class is an implementation of the AbstractButton class. As such, it has methods to set the icons, text strings, icon and text string locations, and other methods of AbstractButton. The JButton itself sends an ActionEvent to all registered ActionListeners when it is clicked and released.
JCheckBox is another descendant of AbstractButton, inheriting from the intermediary class ToggleButton. Determining it's state is done by the isSelected() method of AbstractButton.
JRadioButton is another extension of JToggleButton. They are used within a ButtonGroup so that only one JRadioButton of a given ButtonGroup may be selected at one time. An example of code that would create two JRadioButtons of which only one could be set is this:
JRadioButton firstradiobutton=new JRadioButton("One");
JRadioButton secondradiobutton=new JRadioButton("Two");
ButtonGroup buttongroup=new ButtonGroup();
Thus when the radio buttons were added to a given container only one could be selected at a time exclusionary of the other.
JComboBox is an implementation of a combination text field and drop-down selection. It is based on a ComboBoxModel to describe the data and a ListCellRenderer to display the data. It has methods to get and set the selected item.
The JList component maintains a list of objects and which is selected. Like JComboBox, it uses a ListDataRenderer to display it's contained objects' information.
The JMenuBar is a container that holds JMenu components. Also, it has other methods to affect menu actions based on key or mouse actions.
Normally, it is created then set as the JMenuBar of a JFrame or JRootPane.
JMenus display their contents of JMenuItems (which JMenu extends) when their identifier is selected and activated on their JMenuBar.
The JMenuItem extends AbstractButton. JMenuItems are used to populate the contents of JMenus.
The JPopupMenu is a lightweight menu. It is used as the implementation of JMenu, and JMenuItems are it's contents.
The JProgressBar is used to display incrementality. A BoundedRangeModel is used as the model for the JProgressBar's view.
JScrollBar is an implementation of a user interface component to scroll through components that are too large to fit into the current JViewport.
The JSlider is a component that allows it's value to be set by dragging a conceptual slider through a given range, based on a BoundedRangeModel. It generates ChangeEvents.
JTextArea is a swing analog to the AWT's TextArea, a multi-line text display component, and performs similarly in some respects. It's data model is based on swing.text.Document, as are other text editing and display objects.
JTextField is a single line text display component. It's data is based on a given swing.text.Document, similarly to the other JTextComponents.
The JPasswordField extends JTextField, and is used when sensitive contents are to be entered. An echo character is set and this character is displayed to reflect the contents of the JPasswordField instead of the actual characters.
The JEditorPane is an implementation of JTextComponent that allows the display and editing of arbitrary information based on a given EditorKit for that content type, for example text or HTML.
JTextPane is another text component. It extends JEditorPane, with it's default EditorKit implementation a swing.text.StyledEditorKit. This is sufficient to textually utilize paragraphs, line formatting, etcetera as provided by the StyledDocument data model.
The JToolBar is used to group a set of commonly used actions as components and allow the JToolBar to float separately form the general user interface.
The JToolTip is used to diplay a lightweight popup label over JComponents that have called the setToolTip() method. This can serve as information on the component's function.
Swing has the facility to make borders around arbitrary components. The components to enable this are in the swing.border package.
For any given JComponent, set it's border using the setBorder(Border border) method.
JLabel label=new JLabel("Label");
The swing.table package contains classes that regulate the creation, display, and use of JTable components. The JTable class itself is in the swing package. JTables are JComponents to display tabular data in a row/column format.
There are these interfaces in the swing.table package: TableCellEditor, TableCellRenderer, TableColumnModel, and TableModel.
The TableCellRenderer interface defines the display of a cell's data within the table. For example textual data might simply be drawn to the table's cell as a string, while graphical data within a cell would be represented as an image.
The TableCellEditor interface is implemented to create the component that modifies a table's cell. For example, a common TableCelleditor would be simple text field, but if the cell contained non-textual data or data from a constrained set, the TableCelleditor might be an image editor or data selection dialog.
These are the classes in the swing.table package: AbstractTableModel, DefaultTableCellRenderer, DefaultTableColumnModel, DefaultTableModel, JTableHeader, and TableColumn.
The AbstractTableModel class is used as a convenience for creating TableModel implementations. It provides most of the functionality to create a TableModel except for the methods to get row and column count and to get the value of the TableModel's cell.
The DefaultTableCellRenderer is a provided implementation of TableCellRenderer that displays it's values using a static control as JLabel.
DefaultTableColumnModel is a provided implementation of TableColumnModel.
A DefaultTableModel stores a JTable's data objects as a vector of vectors.
JTableHeader implements TableColumnModelListener and is used to resize and reorder columns within the JTable.
The TableModel class is used to set the values of a JTable's column.
The swing.tree package's classes control the creation, display, and use of JTree components. The JTree class itself is in the swing package. JTree are used to represent hierarchical data, and they can be expanded or collapsed to represent different levels of the data.
There are these interfaces in the swing.tree package: MutableTreeNode, RowMapper, TreeCellEditor, TreeCellRenderer, TreeModel, TreeNode, and TreeSelectionModel.
There are these classes in the swing.tree package: DefaultMutableTreeNode, DefaultTreeModel, DefaultTreeSelectionModel, and TreePath.
The swing.text package contains a variety of classes for viewing and editing text. Using the model-view-controller paradigm, swing text components provide very flexible creation of editing and viewing components.
One of the most commonly used elements of the text package is the Document interface. The Document containers the textual and structural data of the text. This interface represents a logical document, and supports the tracking of DocumentEvents.
For the most part, text actions in Swing are done with the Document Interface.
Characters in a Document are numbered. They start at zero. There are many text manipulation methods in the Document class.
Document data is managed with structured positions and some other abstractions of Document data.
The StyledDocument extends Document to support alternate content.
TextDocuments can be connected to KeyMaps. By doing so meta-key combinations can be used to affect actions as defined by the Action interface.
The keyTyped event is propagated when the Input Method has sent a unicode character to the component.
The keyPressed and keyReleased events are send on key presses and releases respectively. These go to a processKeyEvent() method of a JComponent, which allows FocusManager and other processes to interact with the key events as part of the Document model.
KeyBindings are hierarchical so if a component doesn't handle a key it can be sent to registered listening parent component.
The EditorKit object provides baseline support for document structuring and view creation. By extending and customizing EditorKit you can add support for new content types.
Essentially, the EditorKit is the Controller of the JComponent text handling Model/View/Controller paradigm.
By extending EditorKit you can get an InputStream to the Document's data and perform lexical analysis or other changes.
EditorKit extensions offers a good platform for XML content.
Working with the text of the document itself is best done through the Document interface and DocumentEvents.
The Element interface is a part of the text API that can be used to manage higher level document elements such as pages and chapters. Elements are also associated with other document style features.
Other classes in the swing package include a variety of classes to manage the user interface, some new layouts, and some other utility classes.
Another feature that is important in Swing is the use of the Action interface. Using Actions, required processes are separated from the user interface and can be aggregated or grouped with them.
ProgressMonitor is an object that can be used to provide the user task process completion information. ProgressMonitorInputStream can be used with java.io.InputStream.
RepaintManager can be used to selectively repaint certain areas to improve performance.
The SwingConstants interface has a variety of static variables to regulate positional data. It is implemented by classes that use relative positional data such as JLabel. It's constants are eight compass directions (EAST, NORTHEAST, NORTH, etc), LEFT, RIGHT, TOP, and BOTTOM, CENTER, HORIZONTAL, and VERTICAL.
The SwingUtilities class has methods for working with threads and other utility methods. Use the invokeLater(Runnable runnable) method to start a thread outside of the event dispatching thread. The static invokeAndWait(Runnable runnable) method is a blocking method that will not return until the event-dispatching thread has run the Runnable. The other utility methods of SwingUtilities include useful accessibility functions and other features.
Look and Feel
As a benefit of using the model-view-controller component architecture, Swing components may have a variety of visual representations. This system of modifiable visual component implementations is called "Pluggable Look and Feel". To create a new look, components are created that implement the abstract classes of the swing.plaf package.
This package is removed from the documented hierarchy, but is still very much used by the underlying system to handle the look and feel of displayed components.
The swing.undo package enables the ability to store user actions and undo/redo those actions.
There are these interfaces in the swing.undo package: StateEditable and UndoableEdit.
There are these classes in the swing.undo package: AbstractUndoableEdit, CompoundEdit, StateEdit, UndoManager, and UndoableEditSupport.
There are these exceptions in the swing.undo package: CannotRedoException, CannotUndoException.
The Undo API uses an EventListener model as described above to handle and delegate undo/redo events.
The Undo API is used to incrementally undo and/or redo user actions. The basic interface for this package is the UndoableEdit interface. This interface represents a change which which has been registered as undoable.
This interface has these methods:
public void undo()
public void redo()
As registered changes are made, they are added to a list of undoable edits if they are significant edits. At that point and after, these changes may be reversed and redone.
This package contains the Undo API:
Swing and Accessibility
It is important that graphical user interfaces offer alternative displays for limited viewers. The Accessibility API which is well built with Swing provides functionality for completion of Accessibility requirements.
There is more about the Accessibility API in Chapter Eight.
Using Swing components is a generally positive experience. The Model/View/Controller architecture offers an impressive and expressive array of graphical user interface creation.
JFC Manual Table of Contents
This document may be viewed and printed for personal or educational use. It may not otherwise be redistributed, transmitted, or stored in electronic, paper, or other form without the written consent of the author. The diagrams contained herein may be redistributed, transmitted, or stored as long as they are not modified. For print and redistribution requirements contact Ross A. Finlayson, email@example.com. Java (tm) is a copyright of Sun Microsystems Inc. © 1998 Finlayson Consulting All rights reserved.