Introduction to Java Swing GUI Basics
Introduction to Java Swing GUI Basics
Introducing Swing: The Origin of Swing, Swing Is Built on AWT, Two Key Swing Features, The MVC
Connection, Components and Containers, The Swing Packages, A Simple Swing Application, Event
Handling, Painting in Swing.
Exploring Swing : JLabel and ImageIcon,JTextField,The Swing Buttons-JButton, JToggleButton,
Check Boxes, Radio Buttons
Swing is a powerful and flexible GUI (Graphical User Interface) toolkit in Java that provides a
richer set of components than the earlier AWT (Abstract Window Toolkit). It is part of the Java
Foundation Classes (JFC) and allows developers to create window-based applications with an easier
and more visually appealing interface.
Here are some key features and concepts related to Swing in Java:
Lightweight Components:
Swing components are lightweight, meaning they are drawn entirely in Java rather than relying on the
native system’s GUI components. This provides a consistent look and feel across different platforms.
Pluggable Look and Feel:
Swing supports a pluggable look-and-feel system that allows developers to change the appearance of
their applications dynamically. You can choose from several built-in themes or create your own.
Rich Set of Components:
Swing provides a wide variety of components, including buttons, labels, text fields, tables, trees, and
more. This allows developers to create complex user interfaces.
Event Handling:
Swing includes a robust event handling mechanism, which lets developers respond to user interactions
(like clicks, keyboard input, etc.) easily using listeners.
Swing components can be easily customized and extended to create new components that fit specific
application needs.
Swing follows the Model-View-Controller (MVC) design pattern, allowing for better separation
between the data (model), user interface (view), and the control logic (controller).
Basic Components of Swing:
JFrame: The main window that holds all other Swing components.
JPanel: A generic container used to organize components within a JFrame.
JButton: A clickable button that can perform actions.
JLabel: Displays a short string or an image icon.
JTextField: Allows for single-line text input.
JTextArea: Allows for multi-line text input.
JComboBox: A dropdown list from which users can select an option.
JMenuBar: A menu bar containing menus that can have items and sub-items.
Here's a basic Swing application that creates a window with a button and a label.
package Swings;
import [Link].*;
import [Link];
import [Link];
// Create a button
JButton button = new JButton("Click Me!");
// Create a label
JLabel label = new JLabel("Welcome to Swing!");
o/p
Swing did not exist in the early days of Java. Rather, it was a response to deficiencies present
in Java’s original GUI subsystem: the Abstract Window Toolkit. The AWT defines a basic set
of controls, windows, and dialog boxes that support a usable, but limited graphical interface.
One reason for the limited nature of the AWT is that it translates its various visual components
into their corresponding, platform-specific equivalents, or peers. This means that the look
and feel of a component is defined by the platform, not by Java. Because the AWT components
use native code resources, they are referred to as heavyweight.
The use of native peers led to several problems. First, because of variations between
operating systems, a component might look, or even act, differently on different platforms.
This potential variability threatened the overarching philosophy of Java: write once, run
anywhere. Second, the look and feel of each component was fixed (because it is defined by
the platform) and could not be (easily) changed. Third, the use of heavyweight components
caused some frustrating restrictions. For example, a heavyweight component was always
opaque.
Not long after Java’s original release, it became apparent that the limitations and
restrictions present in the AWT were sufficiently serious that a better approach was needed.
The solution was Swing. Introduced in 1997, Swing was included as part of the Java Foundation
Classes (JFC). Swing was initially available for use with Java 1.1 as a separate library. However,
beginning with Java 1.2, Swing (and the rest of the JFC) was fully integrated into Java.
Before moving on, it is necessary to make one important point: although Swing eliminates
a number of the limitations inherent in the AWT, Swing does not replace it. Instead, Swing is
built on the foundation of the AWT. This is why the AWT is still a crucial part of Java. Swing
also uses the same event handling mechanism as the AWT. Therefore, a basic understanding
of the AWT and of event handling is required to use Swing. (The AWT is covered in
Chapters 25 and 26. Event handling is described in Chapter 24.)
Two Key Swing Features
As just explained, Swing was created to address the limitations present in the AWT. It does
this through two key features: lightweight components and a pluggable look and feel.
Together they provide an elegant, yet easy-to-use solution to the problems of the AWT.
More than anything else, it is these two features that define the essence of Swing. Each
is examined here.
The MVC architecture is successful because each piece of the design corresponds to an aspect of a
component. In MVC terminology, the model corresponds to the state information associated with the
component. For example, in the case of a check box, the model contains a field that indicates if the box
is checked or unchecked. The view determines how the component is displayed on the screen,
including any aspects of the view that are affected by the current state of the model. The controller
determines how the component reacts to the user. For example, when the user clicks a check box, the
controller reacts by changing the model to reflect the user’s choice (checked or unchecked). This then
results in the view being updated. By separating a component into a model, a view, and a controller, the
specific implementation of each can be changed without affecting the other two. For instance,
different view implementations can render the same component in different ways without affecting the
model or the controller.
Although the MVC architecture and the principles behind it are conceptually sound,
the high level of separation between the view and the controller is not beneficial for Swing
components. Instead, Swing uses a modified version of MVC that combines the view and
the controller into a single logical entity called the UI delegate. For this reason, Swing’s
approach is called either the Model-Delegate architecture or the Separable Model architecture.
Therefore, although Swing’s component architecture is based on MVC, it does not use a
classical implementation of it.
Swing’s pluggable look and feel is made possible by its Model-Delegate architecture.
Because the view (look) and controller (feel) are separate from the model, the look and
feel can be changed without affecting how the component is used within a program.
Conversely, it is possible to customize the model without affecting the way that the
component appears on the screen or responds to user input.
To support the Model-Delegate architecture, most Swing components contain two
objects. The first represents the model. The second represents the UI delegate. Models are
defined by interfaces. For example, the model for a button is defined by the ButtonModel
interface. UI delegates are classes that inherit ComponentUI. For example, the UI delegate
for a button is ButtonUI. Normally, your programs will not interact directly with the UI
delegate.
A Swing GUI consists of two key items: components and containers. However, this distinction is
mostly conceptual because all containers are also components. The difference between the two is
found in their intended purpose: As the term is commonly used, a component is an
independent visual control, such as a push button or slider. A container holds a group of
components. Thus, a container is a special type of component that is designed to hold
other components. Furthermore, in order for a component to be displayed, it must be held
within a container. Thus, all Swing GUIs will have at least one container. Because containers
are components, a container can also hold other containers. This enables Swing to define
what is called a containment hierarchy, at the top of which must be a top-level container.
Let’s look a bit more closely at components and containers.
Components
In general, Swing components are derived from the JComponent class. (The only exceptions
to this are the four top-level containers, described in the next section.) JComponent provides
the functionality that is common to all components. For example, JComponent supports the
pluggable look and feel. JComponent inherits the AWT classes Container and Component.
Thus, a Swing component is built on and compatible with an AWT component.
All of Swing’s components are represented by classes defined within the package
[Link]. The following table shows the class names for Swing components (including
those used as containers)
Notice that all component classes begin with the letter J. For example, the class for a label
is JLabel; the class for a push button is JButton; and the class for a scroll bar is JScrollBar.
Containers
Swing defines two types of containers. The first are top-level containers: JFrame, JApplet,
JWindow, and JDialog. These containers do not inherit JComponent. They do, however,
inherit the AWT classes Component and Container. Unlike Swing’s other components,
which are lightweight, the top-level containers are heavyweight. This makes the top-level
containers a special case in the Swing component library.
As the name implies, a top-level container must be at the top of a containment hierarchy.
A top-level container is not contained within any other container. Furthermore, every
containment hierarchy must begin with a top-level container. The one most commonly
used for applications is JFrame. The one used for applets is JApplet.
The second type of containers supported by Swing are lightweight containers. Lightweight
containers do inherit JComponent. An example of a lightweight container is JPanel, which
is a general-purpose container. Lightweight containers are often used to organize and manage
groups of related components because a lightweight container can be contained within
another container. Thus, you can use lightweight containers such as JPanel to create
subgroups of related controls that are contained within an outer container.
Each top-level container defines a set of panes. At the top of the hierarchy is an instance
of JRootPane. JRootPane is a lightweight container whose purpose is to manage the other
panes. It also helps manage the optional menu bar. The panes that comprise the root pane
are called the glass pane, the content pane, and the layered pane.
The glass pane is the top-level pane. It sits above and completely covers all other panes.
By default, it is a transparent instance of JPanel. The glass pane enables you to manage
mouse events that affect the entire container (rather than an individual control) or to paint
over any other component, for example. In most cases, you won’t need to use the glass
pane directly, but it is there if you need it.
The layered pane is an instance of JLayeredPane. The layered pane allows components
to be given a depth value. This value determines which component overlays another. (Thus,
the layered pane lets you specify a Z-order for a component, although this is not something
that you will usually need to do.) The layered pane holds the content pane and the (optional)
menu bar.
Although the glass pane and the layered panes are integral to the operation of a top-level
container and serve important purposes, much of what they provide occurs behind the scene.
The pane with which your application will interact the most is the content pane, because
this is the pane to which you will add visual components. In other words, when you add a
component, such as a button, to a top-level container, you will add it to the content pane.
By default, the content pane is an opaque instance of JPanel.
Swing is a very large subsystem and makes use of many packages. At the time of this writing,
these are the packages defined by Swing.
The main package is [Link]. This package must be imported into any program that
uses Swing. It contains the classes that implement the basic Swing components, such as
push buttons, labels, and check boxes.
Swing programs differ from both the console-based programs and the AWT-based programs
shown earlier in this book. For example, they use a different set of components and a different
container hierarchy than does the AWT. Swing programs also have special requirements that
relate to threading. The best way to understand the structure of a Swing program is to work
through an example. There are two types of Java programs in which Swing is typically used.
The first is a desktop application. The second is the applet. This section shows how to create
a Swing application. The creation of a Swing applet is described later in this chapter.
Although quite short, the following program shows one way to write a Swing
application. In the process, it demonstrates several key features of Swing. It uses two Swing
components: JFrame and JLabel. JFrame is the top-level container that is commonly used
for Swing applications. JLabel is the Swing component that creates a label, which is a
component that displays information. The label is Swing’s simplest component because
it is passive. That is, a label does not respond to user input. It just displays output. The
program uses a JFrame container to hold an instance of a JLabel. The label displays a
short text message.
package Swings;
import [Link];
import [Link];
The event handling mechanism used by Swing is the same as that used by the AWT. This approach is
called the delegation event model, and In many cases, Swing uses the same events as does the AWT,
and these events are packaged in [Link]. Events specific to Swing are stored in
[Link].
package Swings;
import [Link];
import [Link];
import [Link];
import [Link].*;
public class ButtonExample{
JLabel l1;
ButtonExample(){
JFrame f=new JFrame("Button Example");
l1=new JLabel();
[Link](50,50, 700,100);
[Link](new Font("Lucida Calligraphy",[Link],60));
[Link](100,200,100, 100);
[Link](new ActionListener(){
public void actionPerformed(ActionEvent e){
[Link]("India is pressed");
}
});
[Link](400,200,100, 100);
[Link](new ActionListener(){
public void actionPerformed(ActionEvent e){
[Link]("SriLanka is pressed");
}
});
[Link](b1);
[Link](b2);
[Link](l1);
[Link](300,400);
[Link](null);
[Link](true);
[Link](JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new ButtonExample();
}
}
A Paint Example
Here is a program that puts into action the preceding discussion. It creates a class called PaintPanel that
extends JPanel. The program then uses an object of that class to display lines whose endpoints have
been generated randomly. Sample output is shown in Figure
package Swings;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
// Construct a panel
PaintPanel() {
// Put a border around the panel
setBorder([Link]([Link], 5));
rand = new Random();
}
public PaintDemo() {
// Create a new JFrame container
jfrm = new JFrame("Paint Demo");
o/p
ImageButtonExample
package Swings;
import [Link];
import [Link];
import [Link];
import [Link].*;
public class ImageButtonExample {
JLabel l1;
ImageButtonExample (){
JFrame f=new JFrame("Image Button Example");
l1=new JLabel();
[Link](50,50, 700,100);
[Link](new Font("Lucida Calligraphy",[Link],20));
[Link](new ActionListener(){
public void actionPerformed(ActionEvent e){
[Link]("You have pressed digital clock!");
}
});
[Link](new ActionListener(){
public void actionPerformed(ActionEvent e){
[Link]("You have pressed hour glass!");
}
});
[Link](b);
[Link](l1);
[Link](300,400);
[Link](b1);
[Link](l1);
[Link](300,400);
[Link](null);
[Link](true);
[Link](JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new ImageButtonExample();
}
}
JList Example
package Swings;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
Login Form
package Swings;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class login {
// Creating JLabel
JLabel userLabel = new JLabel("User");
JLabel jl= new JLabel();
[Link](30,130,400,40);
[Link](new Font("Arial", [Link], 24));
}
Tabbed Pane Example
package Swings;
import [Link];
import [Link].*;
public class TabbedPaneExample {
JFrame f;
TabbedPaneExample(){
f=new JFrame();
package Swings;
import [Link].*;
import [Link].*;
Graphics g1=getGraphics();
[Link]([Link]);
[Link](oneX, oneY,20,20);
//[Link](oneX, oneY, 6, 6);
}
}
try {
[Link](10);
[Link](() -> [Link]());
} catch (InterruptedException exc) {
[Link]().interrupt();
break;
}
}
}
}
package Swings;
import [Link].*;
import [Link].*;
public class MouseListenerExample2 extends Frame implements MouseListener
{
Label l;
MouseListenerExample2(){
addMouseListener(this);
l=new Label();
[Link](20,50,400,20);
[Link](new Font("Arial", [Link], 24));
add(l);
setSize(300,300);
setLayout(null);
setVisible(true);
}
public void mouseClicked(MouseEvent e) {
Graphics g=getGraphics();
[Link]([Link]);
[Link]([Link](),[Link](),30,30);
}
public void mouseEntered(MouseEvent e) {
[Link]("Mouse Entered");
}
public void mouseExited(MouseEvent e) {
[Link]("Mouse Exited");
}
public void mousePressed(MouseEvent e) {
[Link]("Mouse Pressed");
}
public void mouseReleased(MouseEvent e) {
[Link]("Mouse Released");
}
//public void mouseEntered(MouseEvent e) {}
//public void mouseExited(MouseEvent e) {}
//public void mousePressed(MouseEvent e) {}
//public void mouseReleased(MouseEvent e) {}
package Swings;
import [Link];
import [Link];
package Swings;
import [Link].*;
import [Link].*;
import [Link].*;
public FactorialCalculator() {
// Set up the frame
setTitle("Factorial Calculator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
// Create components
JLabel inputLabel = new JLabel("Enter a number: ");
inputField = new JTextField(10);
JLabel resultLabel = new JLabel("Factorial: ");
resultField = new JTextField(15);
[Link](false);
computeButton = new JButton("Compute");
[Link] = 0;
[Link] = 0;
add(inputLabel, gbc);
[Link] = 1;
[Link] = 0;
add(inputField, gbc);
[Link] = 0;
[Link] = 1;
add(resultLabel, gbc);
[Link] = 1;
[Link] = 1;
add(resultField, gbc);
[Link] = 0;
[Link] = 2;
[Link] = 2;
[Link] = [Link];
add(computeButton, gbc);
package Swings;
import [Link].*;
import [Link].*;
import [Link].*;
public TextCaseConvertor() {
// Set up the frame
setTitle("String Manipulator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
// Create components
JLabel inputLabel = new JLabel("Enter a string: ");
inputField = new JTextField(20);
// Input row
[Link] = 0;
[Link] = 0;
add(inputLabel, gbc);
[Link] = 1;
add(inputField, gbc);
// Uppercase row
[Link] = 0;
[Link] = 1;
add(upperCaseLabel, gbc);
[Link] = 1;
add(upperCaseField, gbc);
// Lowercase row
[Link] = 0;
[Link] = 2;
add(lowerCaseLabel, gbc);
[Link] = 1;
add(lowerCaseField, gbc);
// Reverse row
[Link] = 0;
[Link] = 3;
add(reverseLabel, gbc);
[Link] = 1;
add(reverseField, gbc);
// Length row
[Link] = 0;
[Link] = 4;
add(lengthLabel, gbc);
[Link] = 1;
add(lengthField, gbc);
// Button row
[Link] = 0;
[Link] = 5;
[Link] = 2;
add(processButton, gbc);
package Swings;
import [Link].*;
import [Link].*;
import [Link].*;
public NumberPalindromeChecker() {
// Set up the frame
setTitle("Number Palindrome Checker");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
// Create components
JLabel inputLabel = new JLabel("Enter a number: ");
inputField = new JTextField(15);
// Input row
[Link] = 0;
[Link] = 0;
add(inputLabel, gbc);
[Link] = 1;
add(inputField, gbc);
// Reverse row
[Link] = 0;
[Link] = 1;
add(reverseLabel, gbc);
[Link] = 1;
add(reverseField, gbc);
// Status row
[Link] = 0;
[Link] = 2;
add(statusLabel, gbc);
[Link] = 1;
[Link](new Color(240, 240, 240));
add(statusField, gbc);
// Button row
[Link] = 0;
[Link] = 3;
[Link] = 2;
add(checkButton, gbc);
ToggleButton
This application creates a simple light switch simulator using a JToggleButton. Here's what the code
does:
1. Creates a window with a toggle button, a status label, and a panel representing a light
2. When the toggle button is clicked:
The status label updates to show whether the light is ON or OFF
The light panel changes color (gray when off, yellow when on)
3. Uses proper layout management with BoxLayout and spacing
4. Follows Swing best practices like running on the Event Dispatch Thread
To run this application:
1. Copy the code into a file named [Link]
2. Compile it: javac [Link]
3. Run it: java ToggleButtonDemo
import [Link].*;
import [Link].*;
import [Link];
import [Link];
public ToggleButtonDemo() {
// Set up the frame
setTitle("Toggle Button Demo");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout(10, 10));
setSize(300, 200);
o/p
Check Boxes
Would you like me to add any additional features or modify the existing functionality? For example, I
could:
Add a submit order button
Include a quantity selector for each topping
Add more styling options
Include a base pizza price
import [Link].*;
import [Link].*;
import [Link];
import [Link];
// Checkbox prices
private final double CHEESE_PRICE = 1.50;
private final double PEPPERONI_PRICE = 2.00;
private final double MUSHROOM_PRICE = 1.75;
private final double OLIVES_PRICE = 1.25;
public CheckboxDemo() {
// Set up the frame
setTitle("Pizza Toppings Selector");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout(10, 10));
setSize(400, 300);
Radio Buttons
Would you like me to add any additional features or modify the existing functionality? For example, I
could:
Add more customization options
Include a delivery/pickup option
Add a quantity selector
Include special instructions input
package Swings;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link];
public RadioButtonDemo() {
setTitle("Pizza Size Selector");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300, 300);
setLocationRelativeTo(null);
// Create title
JLabel titleLabel = new JLabel("Select Pizza Size");
[Link](Component.CENTER_ALIGNMENT);
[Link](titleLabel);
[Link]([Link](20));
[Link](radioPanel);
[Link]([Link](20));
[Link]([Link](20));
[Link](orderButton);