Java, GUI Development
Java Swing Tutorial for Beginners
· Eric B.

Java Swing is the desktop GUI toolkit built into the standard JDK, and this tutorial takes you from an empty main method to a working calculator window. You build your first JFrame, add buttons and text fields, wire click events with an ActionListener, and arrange everything with five layout managers. GeeksProgramming has taught Java since 2014, and the order below mirrors how a student moves from a blank screen to a finished interface.
Every code block runs on a plain JDK with no build tool, no external library, and no IDE plugin. Copy a class into a .java file, compile with javac, run with java, and the window appears. Swing classes live in javax.swing and start with the letter J, which is the fastest way to tell a Swing widget (JButton) from its older AWT cousin (Button).
What Java Swing is and why it replaced AWT
Swing is a set of lightweight GUI components drawn in pure Java, layered on top of the older AWT. AWT (Abstract Window Toolkit) shipped with Java 1.0 in 1996 and maps each widget to a native operating-system control, so its components look and behave differently on Windows, macOS, and Linux. Swing arrived in 1998 with Java 1.2 and paints its own components, which gives you one consistent look across platforms plus a much larger widget set.
Three differences matter when you choose between them:
- Component count. AWT exposes about a dozen heavyweight widgets. Swing adds roughly 40 lightweight components, including
JTable,JTree,JTabbedPane,JSlider, andJFileChooser. - Look and feel. Swing supports pluggable look and feel, so one line switches the whole app between the system theme, the cross-platform Metal theme, and Nimbus.
- Rendering model. AWT delegates drawing to the OS. Swing draws everything itself, which is why a Swing window looks identical on every machine that runs your
.jar.
Swing still ships in every JDK from Java 8 through Java 21, needs no dependency, and remains the default for university coursework and internal company tools. JavaFX is the newer toolkit, but it sits outside the JDK from Java 11 onward and requires extra setup, so most beginner courses start with Swing.
Set up the JDK and run your first program
Install a JDK, then compile and run from the command line to confirm the toolchain works. Download a current long-term-support build (Java 17 or Java 21) from Adoptium, Oracle, or your Linux package manager, then check the version:
java -version
javac -version
Both commands print the same version number when the JDK is on your PATH. Any editor works, though IntelliJ IDEA, Eclipse, and NetBeans add autocomplete and a built-in compiler. Create a folder for the project and save each class below as its own .java file whose name matches the public class.
If you are brand new to the language itself and want a gentler on-ramp before GUIs, the Introduction to Java for Zombies walkthrough covers variables, types, and methods, and My First Java Program: Java for Zombies compiles a console program end to end.
Build your first Swing window with JFrame
A JFrame is the top-level window, and four method calls turn it into a visible frame with a button. The example below sets a title, picks a close behavior, adds one JButton, sizes the window with pack(), then shows it.
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class MainWindow extends JFrame {
public MainWindow() {
setTitle("Hello Swing!");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton button = new JButton("Click me");
getContentPane().add(button);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(MainWindow::new);
}
}
Four lines carry the weight. setDefaultCloseOperation(EXIT_ON_CLOSE) ends the program when the user closes the window; skip it and the JVM keeps running after the window disappears. getContentPane().add(button) puts the button in the frame's content pane, the layer that holds every visible component. pack() shrinks the window to the preferred size of its contents; call setSize(300, 200) instead when you want a fixed size. setVisible(true) paints the window on screen and must come last, after every component is added.
The original version of this example shipped with a bug worth naming: it left out the closing brace on the class, so it failed to compile. The version above closes the class and wraps new MainWindow() in SwingUtilities.invokeLater, which is the correct way to start any Swing program.
Always start on the Event Dispatch Thread
Swing is not thread-safe, so all component work runs on one thread called the Event Dispatch Thread (EDT). SwingUtilities.invokeLater(MainWindow::new) hands construction to the EDT instead of the main thread. Build a GUI off the EDT and you get intermittent freezes, blank panels, and repaint glitches that vanish when you rerun, which makes them hard to trace. Wrap the startup call once and the problem never appears.
Create the core Swing components
Buttons, text fields, labels, and panels are the four components every beginner interface uses. Each one is a class you instantiate and add to a container.
JButton for actions
A JButton triggers an action when clicked. Create it with its label, add it to a container, then attach an ActionListener to respond to clicks.
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
public class ButtonExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Button Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Click me");
button.addActionListener(e ->
JOptionPane.showMessageDialog(frame, "You clicked the button"));
frame.add(button);
frame.setSize(300, 200);
frame.setVisible(true);
});
}
}
The lambda e -> ... is the ActionListener. Its body runs on every click. Before Java 8 you wrote an anonymous new ActionListener() { public void actionPerformed(ActionEvent e) { ... } }, which still works and appears in older code, but the lambda says the same thing in one line. Customize the button with setFont, setForeground, setBackground, setIcon, and setToolTipText to change its appearance.
JTextField for input
A JTextField collects a single line of text. Pass a column count to hint at its width, then read the contents with getText().
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class TextFieldExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Text Field Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTextField textField = new JTextField(20);
textField.addActionListener(e ->
System.out.println("Entered: " + textField.getText()));
frame.add(textField);
frame.setSize(300, 120);
frame.setVisible(true);
});
}
}
The addActionListener on a text field fires when the user presses Enter, which is the simplest way to confirm input. For validation as the user types, attach a DocumentListener to the field's document and check the text on every keystroke. To block invalid input before focus leaves the field, set an InputVerifier. For numbers and dates with a fixed format, JFormattedTextField rejects bad characters on its own.
JLabel for static text
A JLabel shows read-only text or an icon next to another component. Use it to caption a text field or display a result.
JLabel label = new JLabel("Result:");
label.setHorizontalAlignment(JLabel.RIGHT);
JPanel for grouping
A JPanel is an invisible container that groups related components and carries its own layout manager. Nesting panels is how every non-trivial Swing interface gets built: one panel for a toolbar, one for a form, one for a status bar, each with the layout that suits it.
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class PanelExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Panel Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.add(new JButton("One"));
panel.add(new JButton("Two"));
frame.add(panel);
frame.setSize(300, 150);
frame.setVisible(true);
});
}
}
A fresh JPanel uses FlowLayout by default, which is why both buttons sit side by side without any layout configuration.
Master the five Swing layout managers
A layout manager decides where each component sits and how it resizes when the window grows or shrinks. Swing ships several; the five below cover almost every beginner interface. Pick the one whose rule matches the shape you want, and nest panels when one window needs more than one rule.
| Layout manager | Arrangement rule | Best use | | -------------- | ---------------------------------------------- | ---------------------- | | FlowLayout | Left to right, wraps to next row | Toolbars, button rows | | BorderLayout | Five regions: North, South, East, West, Center | Main window frame | | GridLayout | Equal cells in a fixed grid | Calculator keypad | | BoxLayout | Single row or single column | Vertical forms, stacks | | GridBagLayout | Weighted rows and columns | Complex aligned forms |
FlowLayout
FlowLayout lines components up left to right at their preferred size and wraps to a new row when the width runs out. It is the default for JPanel.
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.FlowLayout;
public class FlowLayoutExample {
public static void main(String[] args) {
JFrame frame = new JFrame("FlowLayout Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(new JButton("Button 1"));
frame.add(new JButton("Button 2"));
frame.add(new JButton("Button 3"));
frame.setSize(300, 200);
frame.setVisible(true);
}
}
BorderLayout
BorderLayout splits the container into five regions and is the default for a JFrame. The North and South regions stretch horizontally, East and West stretch vertically, and Center takes all remaining space. Each region holds one component, so add a second one to the same region and it hides the first.
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.BorderLayout;
public class BorderLayoutExample {
public static void main(String[] args) {
JFrame frame = new JFrame("BorderLayout Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JButton("North"), BorderLayout.NORTH);
frame.add(new JButton("South"), BorderLayout.SOUTH);
frame.add(new JButton("East"), BorderLayout.EAST);
frame.add(new JButton("West"), BorderLayout.WEST);
frame.add(new JButton("Center"), BorderLayout.CENTER);
frame.setSize(300, 200);
frame.setVisible(true);
}
}
GridLayout
GridLayout arranges components in equal-sized cells across a fixed number of rows and columns. Every cell is the same size, which makes it the natural fit for a calculator keypad or a number pad.
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.GridLayout;
public class GridLayoutExample {
public static void main(String[] args) {
JFrame frame = new JFrame("GridLayout Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(2, 2));
frame.add(new JButton("Button 1"));
frame.add(new JButton("Button 2"));
frame.add(new JButton("Button 3"));
frame.add(new JButton("Button 4"));
frame.setSize(300, 200);
frame.setVisible(true);
}
}
BoxLayout
BoxLayout stacks components in a single row or single column, controlled by the axis you pass. Use BoxLayout.Y_AXIS for a vertical column and BoxLayout.X_AXIS for a horizontal row.
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BoxLayoutExample {
public static void main(String[] args) {
JFrame frame = new JFrame("BoxLayout Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(new JButton("Button 1"));
panel.add(new JButton("Button 2"));
panel.add(new JButton("Button 3"));
frame.add(panel);
frame.setSize(300, 200);
frame.setVisible(true);
}
}
GridBagLayout
GridBagLayout is the most flexible manager: it places components on a grid where each one can span multiple cells and carry its own weight, fill, and padding through a GridBagConstraints object. It is the right tool once a form needs labels and fields that stay aligned as the window resizes, though its constraint object has a learning curve.
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
public class GridBagLayoutExample {
public static void main(String[] args) {
JFrame frame = new JFrame("GridBagLayout Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(4, 4, 4, 4);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0; gbc.gridy = 0;
frame.add(new JButton("Button 1"), gbc);
gbc.gridx = 1;
frame.add(new JButton("Button 2"), gbc);
gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 2;
frame.add(new JButton("Wide Button 3"), gbc);
frame.setSize(300, 200);
frame.setVisible(true);
}
}
The earlier version of this guide reached for GroupLayout here. GroupLayout exists for GUI-builder tools like the NetBeans Matisse designer, which generates its verbose group definitions for you. When you write layout code by hand, GridBagLayout is the manager to learn, so the example above replaces it.
Combine components into a complete GUI
Real interfaces nest several panels, each with its own layout, inside a frame that uses BorderLayout. The example below puts a button row in the North region and a labeled text field in the Center region, which is the standard pattern for a form with a results area.
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
public class ComplexGUIExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Complex GUI Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
JPanel buttonRow = new JPanel();
buttonRow.add(new JButton("Button 1"));
buttonRow.add(new JButton("Button 2"));
JPanel resultRow = new JPanel(new BorderLayout());
resultRow.add(new JLabel("Result: "), BorderLayout.WEST);
resultRow.add(new JTextField(20), BorderLayout.CENTER);
frame.add(buttonRow, BorderLayout.NORTH);
frame.add(resultRow, BorderLayout.CENTER);
frame.setSize(400, 200);
frame.setVisible(true);
});
}
}
This composition rule scales to any interface. Build one panel per logical group, give each the layout that fits its shape, then drop the panels into the frame's BorderLayout regions.
Build a working calculator
A calculator is the classic Swing project because it exercises layout, events, and state in one screen. The keypad is a GridLayout, the display is a JTextField, and one shared ActionListener reads the clicked button and updates the result.
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.GridLayout;
public class Calculator {
private final JTextField display = new JTextField();
public Calculator() {
JFrame frame = new JFrame("Calculator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
display.setEditable(false);
frame.add(display, BorderLayout.NORTH);
JPanel keypad = new JPanel(new GridLayout(4, 4, 4, 4));
String[] keys = {
"7", "8", "9", "/",
"4", "5", "6", "*",
"1", "2", "3", "-",
"0", "C", "=", "+"
};
for (String key : keys) {
JButton button = new JButton(key);
button.addActionListener(e -> onKey(key));
keypad.add(button);
}
frame.add(keypad, BorderLayout.CENTER);
frame.setSize(280, 320);
frame.setVisible(true);
}
private void onKey(String key) {
switch (key) {
case "C" -> display.setText("");
case "=" -> display.setText(evaluate(display.getText()));
default -> display.setText(display.getText() + key);
}
}
private String evaluate(String expression) {
try {
// Demo evaluation only. A graded build parses the expression itself.
return String.valueOf(new javax.script.ScriptEngineManager()
.getEngineByName("JavaScript").eval(expression));
} catch (Exception ex) {
return "Error";
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(Calculator::new);
}
}
Two pieces make it work. The for loop builds 16 buttons from one string array, so the keypad code stays short instead of repeating new JButton 16 times. The shared onKey method handles every button: C clears the display, = evaluates the expression, and any digit or operator appends to the current text. The Nashorn ScriptEngine shortcut keeps the example readable; a graded assignment writes its own parser, because Nashorn was removed in Java 15 and most rubrics ban scripting engines for an arithmetic task.
Apply five Swing best practices
Five habits separate a Swing program that holds up from one that freezes or looks broken. Apply them from the first window rather than retrofitting them later.
- Run on the EDT. Start every GUI inside
SwingUtilities.invokeLater(...), and move file reads, database queries, and network calls onto aSwingWorkerso the interface never freezes while work runs. - Prefer composition over
extends JFrame. Hold aJFrameas a field instead of extending it. Your class stays focused on its own logic rather than inheriting 200-plus window methods you never call. - Let layout managers do the work. Avoid
setBoundswith absolute pixel positions; a hard-coded layout breaks the moment the user resizes the window or runs a different screen resolution. - Set the look and feel once. Call
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName())before building any component so the app matches the host operating system. - Test resize behavior early. Drag the window edges while building, not at the end. A layout that looks right at the default size often collapses when stretched, and the fix is cheaper before the screen fills up.
Reading and writing files is the next skill most Swing apps need, since a real interface saves and loads data. The Java Input/Output (I/O) Guide on file handling covers FileReader, BufferedWriter, and the streams a Swing app wires to its Save and Open buttons.
Where to get Java Swing help
A stuck Swing assignment usually comes down to a layout that will not align, an event that never fires, or a window that renders blank, and each has a known cause. The blank-window cases trace to thread or sizing mistakes; the silent-button cases trace to a missing addActionListener; the misaligned forms trace to the wrong layout manager. Working through the examples above in order resolves most of them.
When a deadline is close or the project has grown past a single window, Java assignment help from GeeksProgramming pairs you with a developer who writes the Swing code, matches your JDK version, and explains the logic so you can answer questions about it. The service has run since 2014, holds a 4.7 out of 5 rating across 350-plus reviews on Google and other platforms, and posts a 95 percent first-attempt pass rate. Pricing starts at $29, you pay 50 percent upfront and 50 percent on delivery, and an NDA keeps the work private.
Frequently asked questions
Is Java Swing still used in 2026?
Yes. Swing ships inside every standard JDK, runs on Java 8 through Java 21 with no extra dependency, and stays the default choice for university coursework and internal desktop tools. JavaFX is the newer toolkit, but most CS courses and legacy enterprise apps still teach and run Swing because it needs zero setup beyond the JDK.
What is the difference between AWT and Swing?
AWT maps each component to a native operating-system widget, so it offers a small set of heavyweight components that look different on every platform. Swing draws its own lightweight components in pure Java, gives you roughly 40 ready-made widgets, supports pluggable look and feel, and renders the same on Windows, macOS, and Linux. Swing classes start with J: JButton, JFrame, JPanel.
Why does my Swing window appear blank or empty?
Three causes account for most blank windows. You added components after calling setVisible(true) without calling revalidate(); you forgot pack() or setSize() so the frame has zero size; or you added two components to a BorderLayout region, where the second one hides the first. Add every component before showing the frame, then call pack().
How do I handle a button click in Swing?
Register an ActionListener on the button. Call button.addActionListener(e -> { ... }) with a lambda, or pass an anonymous class that overrides actionPerformed(ActionEvent e). The code inside runs each time the user clicks. The same pattern handles menu items, JTextField Enter presses, and Timer ticks.
Should I extend JFrame or hold one as a field?
Hold a JFrame as a field through composition rather than extending it. Extending JFrame ties your class to a window and exposes 200-plus inherited methods you never use. Composition keeps your class focused on its own logic and matches how Swing code past the beginner stage is written.
Why must Swing code run on the Event Dispatch Thread?
Swing is not thread-safe. Creating or updating components from any thread other than the Event Dispatch Thread (EDT) causes random freezes, missing repaints, and deadlocks. Start your GUI inside SwingUtilities.invokeLater(() -> ...) so construction happens on the EDT, and move slow work onto a SwingWorker so the interface stays responsive.
Which layout manager should a beginner learn first?
Learn BorderLayout and FlowLayout first, then GridLayout. BorderLayout is the default for a JFrame and splits a window into five regions. FlowLayout lines components up left to right. GridLayout builds equal cells, ideal for a calculator keypad. Combine them with nested JPanel containers to build almost any interface before you reach GridBagLayout.
Can I get help with a Java Swing assignment?
Yes. GeeksProgramming has provided Java assignment help since 2014, including Swing GUI projects, layout debugging, and event-handling tasks. A dedicated Java developer writes the code, matches your JDK version, and walks you through the logic so you can defend the work. Pricing starts at $29, with a 50 percent upfront and 50 percent on delivery split.
Related articles
- Java
Java Concurrency and Multithreading Guide
Learn Java multithreading from threads and synchronization to thread pools, the memory model, and concurrent collections, with runnable code examples.
Sep 12, 2023
- Java
Java Collections Framework Explained
A practical Java Collections guide covering List, Set, Queue, Map, Comparable, the Collections utility class, time complexity, and Stream API with runnable code.
Sep 4, 2023
- Java
Advanced Java Data Management Techniques
Master advanced Java data management: optimize data structures, handle concurrent access, tune memory, and use serialization and compression in real applications.
May 3, 2024


