Jump to content

Swing (Java)

From Alfawiki
Swing
Company typeSoftware toolkit
IndustrySoftware development, Graphical user interface
PredecessorAbstract Window Toolkit (AWT)
Founded1997
FounderSun Microsystems, Netscape Communications Corporation
Headquarters
United States
Area served
Cross-platform (Java platform)
Key people
James Gosling, Rick Levenson, Amy Fowler, Hans Muller, Tom Ball, Jeff Dinkins, Georges Saab, Tim Prinzing, Jonni Kanerva, Jeannette Hung, Jim Graham
ProductsGUI widget toolkit for Java
OwnerOracle Corporation (after acquisition of Sun Microsystems)

Swing is a GUI widget toolkit designed for the Java platform. It forms a part of Oracle’s Java Foundation Classes (JFC), which is an API that supplies graphical user interface capabilities to Java applications.

Created to provide a more sophisticated collection of GUI components than the predecessor AWT, Swing supports a pluggable look and feel system. This feature enables it to mimic various operating system appearances or adopt custom styles, offering enhanced components beyond those available in AWT. In addition to basic elements like buttons and labels, Swing includes advanced widgets such as tabbed panes, scroll panes, trees, tables, and lists.

A significant distinction from AWT is that Swing's components are implemented entirely in Java, ensuring they operate independently of the underlying platform.

In December 2008, Sun Microsystems, which was later acquired by Oracle, introduced JavaFX, a CSS- and FXML-based framework designed to succeed Swing.

History

The Internet Foundation Classes (IFC), a Java graphics toolkit developed by Netscape Communications Corporation, debuted in December 1996. By April 1997, Sun Microsystems and Netscape announced a collaboration to combine IFC with other technologies, leading to the creation of the Java Foundation Classes. Swing emerged as a central element of this effort.

Swing pioneered a system that allowed the entire user interface’s look and feel to be altered without extensive code changes, facilitating platform emulation while remaining platform-agnostic. Initially released as a separate package, Swing has been integrated into the Java Standard Edition since version 1.2. Its classes are located within the package.

Development on Swing’s intended replacement, JavaFX, began in 2005 and was officially unveiled at JavaOne in 2007. Open-sourced in 2011 and incorporated into Oracle JDK by 2012, JavaFX provides benefits such as CSS-based styling, modern UI controls, and FXML support. Since 2018, JavaFX has been included in OpenJDK under the OpenJFX initiative to promote faster innovation.

The primary contributors to Swing’s development on the Java Client team included architect James Gosling, project manager Rick Levenson, co-technical leads Amy Fowler and Hans Muller, alongside developers Tom Ball, Jeff Dinkins, Georges Saab, Tim Prinzing, Jonni Kanerva, Jeannette Hung, and Jim Graham.

Architecture

Swing is a cross-platform "model–view–controller" style GUI framework for Java that operates within a single-threaded programming paradigm. It offers an abstraction layer separating application logic from the graphical representation of Swing-based interfaces.

Foundations

Swing’s ability to run across platforms is due to its complete implementation in Java. Extensive documentation can be found in the Java API Guide for version 6 and the Java Platform Standard Edition 8 API Specification for version 8.

Extensible

The framework boasts a modular design that allows developers to provide custom implementations of its interfaces. Default components can be replaced or extended through Java inheritance mechanisms such as subclassing the class.

As a component-based framework, every Swing component inherits from the class. These components dispatch events asynchronously, support bound properties, and conform to standardized methods. Additionally, Swing components adhere to the JavaBeans specification.

Configurable

Swing offers considerable runtime adaptability, permitting modifications such as hot swapping of user interfaces while the application is running. Custom implementations of look and feel facilitate consistent UI changes across multiple applications without the need to alter the underlying code.

Lightweight UI

Instead of utilizing native operating system GUI controls, Swing renders its components through Java 2D APIs, bypassing native toolkits entirely. As a result, Swing components do not have direct equivalents in the OS’s native GUI elements and can be drawn flexibly using the available graphical resources.

Nonetheless, every Swing component depends on an AWT container because it extends AWT's Container class. This relationship allows Swing to interact with the host operating system’s GUI management system for device mapping and processing user inputs like keyboard and mouse events. Swing translates its platform-independent interface semantics into OS-specific operations, managing its own rendering through component.paint() methods defined within AWT.

This separation applies not only to visual rendering but also to event handling within component hierarchies. Swing leverages AWT’s general event mapping framework to implement rich, platform-neutral GUI semantics via the model.

Loosely coupled and MVC

The Swing framework heavily employs the model–view–controller design pattern, which separates application data from the UI controls. Most Swing components are paired with model objects specified by Java interfaces, giving developers the option to utilize default models or design custom implementations. The framework supplies standard model implementations for all concrete components, so custom models are typically unnecessary except for advanced components such as tables, trees, and lists. For example, custom models may encapsulate DAO or EJB services to better integrate with business data layers.

Model objects in Swing define both events and accessible properties representing the conceptual data associated with their JComponent counterparts. This loosely coupled MVC approach permits event listeners to attach directly to model objects; model-generated events (such as a "row inserted" notification in a table) are then translated by specialized JComponent subclasses into corresponding GUI events.

For instance, utilizes a model named that specifies access patterns for tabular data. Its default implementation operates on a two-dimensional array.

Swing’s view components visually depict GUI controls by rendering them programmatically rather than relying on native OS widgets. Prior to Java 6 Update 10, combining AWT (native) and Swing (lightweight) components often resulted in issues.

When it comes to layout management, Swing prefers relative layouts, which define spatial relationships between components instead of fixed sizes and positions. This responsive layout strategy originated from its applet-era design philosophy, akin to how HTML content is rendered, addressing similar challenges related to adaptable user interfaces.

Relationship to AWT

Since Java’s early releases, the Abstract Window Toolkit (AWT) has provided platform-neutral APIs for UI elements. AWT components depend on native peer widgets tied directly to the underlying windowing system, classifying them as heavyweight components.

Swing components differ as lightweight since they do not rely on native OS resources. Rather than replacing AWT entirely, Swing builds upon it; all top-level Swing containers (, , , and ) inherit from AWT’s top-level containers. Before Java 6 Update 10, mixing lightweight and heavyweight components was generally discouraged due to issues with Z-order rendering conflicts. These problems were addressed in later Java versions, enabling seamless integration of both component types.

Rendering in Swing is based on Java 2D, which is part of the Java Foundation Classes (JFC).

Connection with SWT

The Standard Widget Toolkit (SWT), created by IBM and supported by the Eclipse community, serves as an alternative GUI toolkit that follows a design closer to AWT’s heavyweight components. This approach delivers a more faithful native appearance but introduces greater platform-dependent complexity.

Discussions about performance between SWT and Swing have been ongoing. While SWT relies on the JNI, which might introduce latency in data exchange between the Java environment and the GUI, it can enhance rendering speed once data is loaded. Benchmark tests from 2005 revealed no definitive superior performer overall; instead, outcomes depend on the operating system, with SWT generally faster on Windows and Swing showing better results on Linux or virtualized systems.

Hello World

The following Swing example constructs a window titled "Hello World" that displays the message "Hello, world!":

<syntaxhighlight lang="java"> // Hello.java (Java SE 8) import javax.swing.*;

public class Hello extends JFrame {

   public Hello() {
       super("Hello World");
       setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
       add(new JLabel("Hello, world!"));
       pack();
       setVisible(true);
   }
   public static void main(String[] args) {
       SwingUtilities.invokeLater(Hello::new);
   }

} </syntaxhighlight>

The import directive brings in all accessible classes and interfaces from the javax.swing package.

The Hello class inherits from JFrame, which offers a window featuring a title bar and close button.

Within the Hello() constructor, the superclass constructor is called with "Hello World" as the window title. The default close operation is set to WindowConstants.EXIT_ON_CLOSE, ensuring the application terminates upon window closure. A JLabel displaying "Hello, world!" is added to the frame. The pack() method sizes the window appropriately, followed by setVisible(true) to render it visible.

The main() method initiates the frame creation on the event dispatch thread using SwingUtilities.invokeLater(), guaranteeing thread-safe GUI updates. The program continues running until all Swing windows have been closed.

Window with Button

This straightforward Swing example presents a window containing both a label and a button.

<syntaxhighlight lang="java"> import java.awt.FlowLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.WindowConstants; import javax.swing.SwingUtilities;

public class SwingExample implements Runnable {

   private JFrame f;
   public SwingExample()  {
       f = new JFrame("Hello World!");
       f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
       f.setLayout(new FlowLayout());
       f.add(new JLabel("Hello, world!"));
       f.add(new JButton("Press me!"));   
   }
   @Override
   public void run() {
       f.pack();
       f.setVisible(true);
   }

   public static void main(String[] args) {
       SwingUtilities.invokeLater(new SwingExample());
   }

} </syntaxhighlight>

All interactions with Swing components are managed within an object implementing Runnable, executed on the Event Dispatch Thread through SwingUtilities.invokeLater(). This design ensures thread safety by avoiding concurrency issues and memory consistency errors that may occur when multiple threads access Swing elements simultaneously.

Text Field

Text fields provide a means for users to input data within applications. To create one, you instantiate a JTextField object and add it to a container component.

<syntaxhighlight lang="java"> import javax.swing.*;

public class TextFieldExample {

  public static void main(String[] args) {
      JFrame frame = new JFrame("Text Field Example");
      JTextField textField = new JTextField(20);
      frame.add(textField);
      frame.setSize(300, 200);
      frame.setVisible(true);
  }

} </syntaxhighlight>

Incorporating DocumentListener interfaces into text fields allows for continuous tracking of user input, enabling functionalities such as instant validation, formatting adjustments, or auto-completion features. Utilizing InputVerifier interfaces facilitates strict validation criteria and provides immediate feedback to maintain data accuracy and minimize input mistakes.

Additional Example

Here, the example extends javax.swing.JFrame as the base class and integrates a custom component—a JButton.

<syntaxhighlight lang="java"> import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.JOptionPane; import javax.swing.SwingUtilities;

import java.awt.event.ActionListener; import java.awt.event.ActionEvent;

public class Sample extends JFrame { private final JButton b = new JButton();

public Sample() { super(); this.setTitle("HelloApp"); this.getContentPane().setLayout(null); this.setBounds(100, 100, 180, 140); this.add(createButton()); this.setVisible(true); this.setDefaultCloseOperation(EXIT_ON_CLOSE); }

private JButton createButton() { b.setText("Click me!"); b.setBounds(40, 40, 100, 30); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(b, "Hello World!"); } }); return b; }

public static void main(String[] args) throws InvocationTargetException, InterruptedException { // Swing operations must execute on the event dispatch thread. SwingUtilities.invokeAndWait(() -> new Sample()); } } </syntaxhighlight> The layout manager is explicitly set to null using setLayout because JFrame’s default layout manager is java.awt.BorderLayout, which centers and expands added components. However, most enterprise applications favor using layout managers instead of absolute positioning to achieve greater flexibility.

See also

Sources

  • Matthew Robinson, Pavel Vorobiev: Swing, Second Edition, Manning
  • David M. Geary: Graphic Java 2, Volume 2: Swing, Prentice Hall
  • John Zukowski: The Definitive Guide to Java Swing, Third Edition, Apress
  • James Elliott et al.: Java Swing, O'Reilly
  • Kathy Walrath et al.: The JFC Swing Tutorial: A Guide to Constructing GUIs, Addison-Wesley Professional
  • Joshua Marinacci, Chris Adamson: Swing Hacks, O'Reilly
  • Ivan Portyankin, Swing, Effective User Interfaces (Russian), 2nd Ed., 2010, Moscow, "Lory"

External links