Misplaced Pages

Swing (Java): Difference between revisions

Article snapshot taken from Wikipedia with creative commons attribution-sharealike license. Give it a read and then ask your questions in the chat. We can research this topic together.
Browse history interactively← Previous editNext edit →Content deleted Content addedVisualWikitext
Revision as of 23:00, 19 March 2010 editHervegirod (talk | contribs)Autopatrolled, Extended confirmed users15,440 edits Relationship to SWT← Previous edit Revision as of 23:14, 19 March 2010 edit undoHervegirod (talk | contribs)Autopatrolled, Extended confirmed users15,440 edits A basic example: all this part about thread safety in Swing is a repeat from the previous paragraph, and is more in its place in the ADT articleNext edit →
Line 107: Line 107:
The following is a rather simple Swing-based program. It displays window (a {{Javadoc:SE|javax/swing|JFrame}}) containing a label and a button. The example will compile cleanly if put in a file SwingExample.java (For the ], it is possible to copy the code below, highlight a project node in Eclipse and simply hit paste). The following is a rather simple Swing-based program. It displays window (a {{Javadoc:SE|javax/swing|JFrame}}) containing a label and a button. The example will compile cleanly if put in a file SwingExample.java (For the ], it is possible to copy the code below, highlight a project node in Eclipse and simply hit paste).


Notice how all instantiation and handling of all Swing components are done on the ] by use of the method <code>EventQueue.invokeLater(..)</code> and an anonymous Runnable class (see ]).
Notice how all instantiation and handling of all Swing components is done on the ] by use of the method <code>EventQueue.invokeLater(..)</code> and an anonymous Runnable class. More about this requirement can be read in the Concurrency chapter of the on the Sun website - not adhering to this rule may sometimes cause subtle bugs that are next to impossible to track down<ref name="earlier version of Swing threading tutorial">http://life.csu.edu.au/java-tut/uiswing/misc/threads.html</ref><ref>http://weblogs.java.net/blog/alexfromsun/archive/2005/11/debugging_swing_1.html</ref>. This particular issue has also been discussed as a with several links to further resources, where it is pointed out that the rules for this changed in 2004. A popular third-party ] named goes as far as to refuse to instantiate any Swing component off of the Event Dispatch Thread<ref>http://www.pushing-pixels.org/?p=368</ref>, to hinder coders from making such a mistake.
<source lang="java"> <source lang="java">
// Import the swing and AWT classes needed // Import the swing and AWT classes needed

Revision as of 23:14, 19 March 2010

Example Swing widgets in Java 5 for the X Window System

Swing is a widget toolkit for Java. It is part of Sun Microsystems' Java Foundation Classes (JFC) — an API for providing a graphical user interface (GUI) for Java programs.

Swing was developed to provide a more sophisticated set of GUI components than the earlier Abstract Window Toolkit. Swing provides a native look and feel that emulates the look and feel of several platforms, and also supports a pluggable look and feel that allows applications to have a look and feel unrelated to the underlying platform.

History

The Internet Foundation Classes (IFC) were a graphics library for Java originally developed by Netscape Communications Corporation and first released on December 16, 1996. On April 2, 1997, Sun Microsystemsnow Oracle and Netscape Communications Corporation announced their intention to incorporate IFC with other technologies to form the Java Foundation Classes.

Swing introduced a mechanism that allowed the look and feel of every component in an application to be altered without making substantial changes to the application code. The introduction of support for a pluggable look and feel allows Swing components to emulate the appearance of native components while still retaining the benefits of platform independence. This feature also makes it easy to make an application written in Swing look very different from native programs if desired.

Originally distributed as a separately downloadable library, Swing has been included as part of the Java Standard Edition since release 1.2. The Swing classes and components are contained in the javax.swing package hierarchy.

Architecture

Swing is a platform-independent, Model-View-Controller GUI framework for Java. It follows a single-threaded programming model, and possesses the following traits:

Foundations

Platform independence

Swing is platform independent both in terms of its expression (Java) and its implementation (non-native universal rendering of widgets).

Extensible

Swing is a highly partitioned architecture, which allows for the "plugging" of various custom implementations of specified framework interfaces: Users can provide their own custom implementation(s) of these components to override the default implementations. In general, Swing users can extend the framework by extending existing (framework) classes and/or providing alternative implementations of core components.

Swing is a component-based framework. The distinction between objects and components is a fairly subtle point: concisely, a component is a well-behaved object with a known/specified characteristic pattern of behaviour. Swing objects asynchronously fire events, have "bound" properties, and respond to a well-known set of commands (specific to the component.) Specifically, Swing components are Java Beans components, compliant with the Java Beans Component Architecture specifications.

Customizable

Given the programmatic rendering model of the Swing framework, fine control over the details of rendering of a component is possible in Swing. As a general pattern, the visual representation of a Swing component is a composition of a standard set of elements, such as a "border", "inset", decorations, etc. Typically, users will programmatically customize a standard Swing component (such as a JTable) by assigning specific Borders, Colors, Backgrounds, opacities, etc., as the properties of that component. The core component will then use these property (settings) to determine the appropriate renderers to use in painting its various aspects. However, it is also completely possible to create unique GUI controls with highly customized visual representation.

Configurable

Swing's heavy reliance on runtime mechanisms and indirect composition patterns allows it to respond at runtime to fundamental changes in its settings. For example, a Swing-based application can change its look and feel at runtime. Further, users can provide their own look and feel implementation, which allows for uniform changes in the look and feel of existing Swing applications without any programmatic change to the application code.

Lightweight UI

Swing's configurability is a result of a choice not to use the native host OS's GUI controls for displaying itself. Swing "paints" its controls programmatically through the use of Java 2D APIs, rather than calling into a native user interface toolkit. Thus, a Swing component does not have a corresponding native OS GUI component, and is free to render itself in any way that is possible with the underlying graphics APIs.

However, at its core every Swing component relies on an AWT container, since (Swing's) JComponent extends (AWT's) Container. This allows Swing to plug into the host OS's GUI management framework, including the crucial device/screen mappings and user interactions, such as key presses or mouse movements. Swing simply "transposes" its own (OS agnostic) semantics over the underlying (OS specific) components. So, for example, every Swing component paints its rendition on the graphic device in response to a call to component.paint(), which is defined in (AWT) Container. But unlike AWT components, which delegated the painting to their OS-native "heavyweight" widget, Swing components are responsible for their own rendering.

This transposition and decoupling is not merely visual, and extends to Swing's management and application of its own OS-independent semantics for events fired within its component containment hierarchies. Generally speaking, the Swing Architecture delegates the task of mapping the various flavors of OS GUI semantics onto a simple, but generalized, pattern to the AWT container. Building on that generalized platform, it establishes its own rich and complex GUI semantics in the form of the JComponent model. A review of the source of Container java and JComponent java classes is recommended for further insights into the nature of the interface between Swing's lightweight components and AWT's heavyweight widgets.

Loosely-Coupled/MVC

The Swing library makes heavy use of the Model/View/Controller software design pattern, which conceptually decouples the data being viewed from the user interface controls through which it is viewed. Because of this, most Swing components have associated models (which are specified in terms of Java interfaces), and the programmer can use various default implementations or provide their own. The framework provides default implementations of model interfaces for all of its concrete components.

Typically, Swing component model objects are responsible for providing a concise interface defining events fired, and accessible properties for the (conceptual) data model for use by the associated JComponent. Given that the overall MVC pattern is a loosely-coupled collaborative object relationship pattern, the model provides the programmatic means for attaching event listeners to the data model object. Typically, these events are model centric (ex: a "row inserted" event in a table model) and are mapped by the JComponent specialization into a meaningful event for the GUI component.

For example, the JTable has a model called TableModel that describes an interface for how a table would access tabular data. A default implementation of this operates on a two-dimensional array.

The view component of a Swing JComponent is the object used to graphically "represent" the conceptual GUI control. A distinction of Swing, as a GUI framework, is in its reliance on programmatically-rendered GUI controls (as opposed to the use of the native host OS's GUI controls). Prior to Java 6 Update 10, this distinction was a source of complications when mixing AWT controls, which use native controls, with Swing controls in a GUI (see Mixing AWT and Swing components).

Finally, in terms of visual composition and management, Swing favors relative layouts (which specify the positional relationships between components) as opposed to absolute layouts (which specify the exact location and size of components). This bias towards "fluid"' visual ordering is due to its origins in the applet operating environment that framed the design and development of the original Java GUI toolkit. (Conceptually, this view of the layout management is quite similar to that which informs the rendering of HTML content in browsers, and addresses the same set of concerns that motivated the former.)

Look and feel

See also: Pluggable look and feel

Swing allows one to specialize the look and feel of widgets, by modifying the default (via runtime parameters), deriving from an existing one, by creating one from scratch, or, beginning with J2SE 5.0, by using the skinnable synth Look and Feel (see Synth Look and Feel), which is configured with an XML property file. The look and feel can be changed at runtime, and early demonstrations of Swing frequently provided a way to do this.

Relationship to AWT

AWT and Swing class hierarchy

Since early versions of Java, a portion of the Abstract Window Toolkit (AWT) has provided platform-independent APIs for user interface components. In AWT, each component is rendered and controlled by a native peer component specific to the underlying windowing system.

By contrast, Swing components are often described as lightweight because they do not require allocation of native resources in the operating system's windowing toolkit. The AWT components are referred to as heavyweight components.

Much of the Swing API is generally a complementary extension of the AWT rather than a direct replacement. In fact, every Swing lightweight interface ultimately exists within an AWT heavyweight component because all of the top-level components in Swing (JApplet, JDialog, JFrame, and JWindow) extend an AWT top-level container. However, the use of both lightweight and heavyweight components within the same window is generally discouraged due to Z-order incompatibilities.

The core rendering functionality used by Swing to draw its lightweight components is provided by Java 2D, another part of JFC.

Relationship to SWT

The Standard Widget Toolkit (SWT) is a competing toolkit originally developed by IBM and now maintained by the Eclipse community. SWT's implementation has more in common with the heavyweight components of AWT. This confers benefits such as more accurate fidelity with the underlying native windowing toolkit, at the cost of an increased exposure to the native platform in the programming model.

The advent of SWT has given rise to a great deal of division among Java desktop developers, with many strongly favoring either SWT or Swing. Sun's development on Swing continues to focus on platform look and feel (PLAF) fidelity with each platform's windowing toolkit in the approaching Java SE 7 release (as of December 2006).

There has been significant debate and speculation about the performance of SWT versus Swing; some hinted that SWT's heavy dependence on JNI would make it slower when the GUI component and Java need to communicate data, but faster at rendering when the data model has been loaded into the GUI. A fairly thorough set of benchmarks concluded that neither Swing nor SWT clearly outperformed the other in the general case.

SWT serves the Windows platform very well but is considered by some to be less effective as a technology for cross-platform development. By using the high-level features of each native windowing toolkit, SWT returns to the issues seen in the mid 90's (with toolkits like zApp, Zinc, XVT and IBM/Smalltalk) where toolkits attempted to mask differences in focus behaviour, event triggering and graphical layout. Failure to match behavior on each platform can cause subtle but difficult-to-resolve bugs that impact user interaction and the appearance of the GUI.

Relationship to LWUIT

See also: LWUIT

LWUIT is a UI library for mobile phones, inspired by the Swing architecture.

Debugging

Swing application debugging can be difficult because of the toolkit's visual nature. In contrast to non-visual applications, GUI applications cannot be as easily debugged using step-by-step debuggers.

The main reason is that Swing normally performs painting into an off-screen buffer (double buffering) first and then copies the entire result to the screen. This is to not let the user observe the painting process which would be perceived as flickering. This makes it difficult to observe the impact of each separate graphical operation on the user interface using a general-purpose Java debugger. To help with this problem, one can turn off double buffering, and have the drawing operations visualized using the built-in DebugGraphics object. Also, a free and open source GUI-based debugging application called Swing Explorer will be of help with drawing problems: It will locate which component painted every single pixel in a window, where each component was instantiated, displays the time line for each drawing operation, and will present a "DOM-like" tree of all Components in the JVM along with visualization of where the selected component painted. All operations are done through a side GUI which injects itself into the application, thus making Swing debugging considerably more effective.

There are also some common problems related to the painting thread. Swing uses the AWT event dispatching thread for painting components. In accordance with Swing standards, all components must be created and accessed only from the AWT event dispatch thread. If the application violates this rule, it may cause unpredictable behavior.. The third-party, free and open source pluggable Look and Feel called Substance can help here, as it refuses to handle any components off of the Event Dispatch Thread, thus pinpointing violations to this rule.

If long-running operations are performed in the AWT event dispatch thread, repainting of the Swing user interface temporarily becomes impossible causing screen freezes. Such operations must be moved into a separate thread.

It is worth emphasizing that these problems are not in any way unique to Swing - most GUI toolkits necessarily have similar problem spaces with threading and buffering.

Examples

A basic example

The following is a rather simple Swing-based program. It displays window (a JFrame) containing a label and a button. The example will compile cleanly if put in a file SwingExample.java (For the Eclipse IDE, it is possible to copy the code below, highlight a project node in Eclipse and simply hit paste).

Notice how all instantiation and handling of all Swing components are done on the Event Dispatch Thread by use of the method EventQueue.invokeLater(..) and an anonymous Runnable class (see Swing and thread safety).

// Import the swing and AWT classes needed
import java.awt.EventQueue;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
/**
 * Basic Swing example.
 */
public class SwingExample {
    public static void main(String args) {
        // Make sure all Swing/AWT instantiations and accesses are done on the
        // Event Dispatch Thread (EDT)
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                // Create a JFrame, which is a Window with "decorations", i.e. 
                // title, border and close-button
                JFrame f = new JFrame("Swing Example Window");
                // Set a simple Layout Manager that arranges the contained 
                // Components
                f.setLayout(new FlowLayout());
                // Add some Components
                f.add(new JLabel("Hello world!"));
                f.add(new JButton("Press me!"));
                // "Pack" the window, making it "just big enough".
                f.pack();
                // Set the default close operation for the window, or else the 
                // program won't exit when clicking close button
                //  (The default is HIDE_ON_CLOSE, which just makes the window
                //  invisible, and thus don't exit the app)
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // Set the visibility as true, thereby displaying it
                f.setVisible(true);
            }
        });
    }
}

See also

Notes

  1. Swing as MVC
  2. The typical use of the Swing framework does not require the creation of custom models, as the framework provides a set of default implementations that are transparently, by default, associated with the corresponding JComponent child class in the Swing library. In general, only complex components, such as tables, trees and sometimes lists, may require the custom model implementations around the application-specific data structures. To get a good sense of the potential that the Swing architecture makes possible, consider the hypothetical situation where custom models for tables and lists are wrappers over DAO and/or EJB services.
  3. Swing vs. SWT Performance - Have a Look at the Call Stacks
  4. Igor, Križnar (2005-05-10). "SWT Vs. Swing Performance Comparison" (PDF). cosylab.com. Retrieved 2008-05-24. It is hard to give a rule-of-thumb where SWT would outperform Swing, or vice versa. In some environments (e.g., Windows), SWT is a winner. In others (Linux, VMware hosting Windows), Swing and its redraw optimization outperform SWT significantly. Differences in performance are significant: factors of 2 and more are common, in either direction. {{cite web}}: Check date values in: |date= (help)
  5. DebugGraphics debugging helper
  6. Swing Explorer
  7. http://weblogs.java.net/blog/alexfromsun/archive/2005/11/debugging_swing_1.html

References

  • Matthew Robinson, Pavel Vorobiev: Swing, Second Edition, Manning, ISBN 1-930110-88-X
  • David M. Geary: Graphic Java 2, Volume 2: Swing, Prentice Hall, ISBN 0-13-079667-0
  • John Zukowski: The Definitive Guide to Java Swing, Third Edition, Apress, ISBN 1-590-59447-9
  • James Elliott, Robert Eckstein, Marc Loy, David Wood, Brian Cole: Java Swing, O'Reilly, ISBN 0-596-00408-7
  • Kathy Walrath, Mary Campione, Alison Huml, Sharon Zakhour: The JFC Swing Tutorial: A Guide to Constructing GUIs, Addison-Wesley Professional, ISBN 0-201-91467-0
  • Joshua Marinacci, Chris Adamson: Swing Hacks, O'Reilly, ISBN 0-596-00907-0

External links

List of widget toolkits
Low-level platform-specific
On AmigaOS
On Classic Mac OS, macOS
On Windows
On Unix,
under X11
On BeOS, Haiku
On Android
CLI
Low Level Cross-platform
CLI
C
Java
High-level, platform-specific
On AmigaOS
On Classic Mac OS, macOS
Object Pascal
Objective-C, Swift
C++
CLI
On Windows
CLI
C++
Object Pascal
On Unix,
under X11
On Android
High-level, cross-platform
C
C++
Objective-C
CLI
Adobe Flash
Go
Haskell
Java
JavaScript
Common Lisp
Lua
Pascal
Object Pascal
Perl
PHP
Python
Ruby
Tcl
XML
shell
Dart
Categories: