Advanced Java ProgrammingUnit 415 min read
Swing UI Design & Event Handling in Java
Unit 4 of Advanced Java Programming covers Swing components (JFrame, JPanel, JButton, JLabel, JTextField), layout managers (BorderLayout, GridLayout, FlowLayout), event-driven programming (ActionListener, MouseListener, KeyListener), and building interactive GUIs with JavaFX/Swing integration. Learn through real-world
TAKEAWAYS:
- Swing components (JFrame, JPanel, etc.) are lightweight UI widgets built on AWT, offering customizable appearance and behavior.
- Layout managers (BorderLayout, GridLayout) automatically position components; choose based on design needs (e.g., GridLayout for calculators).
- Event handling uses listeners (ActionListener, MouseListener) to respond to user actions like clicks or keypresses via callback methods.
- JavaFX vs. Swing: JavaFX is modern (CSS styling, hardware acceleration) but Swing remains widely used for legacy systems.
- Common pitfalls: Forgetting to add components to containers or misplacing
add()calls in constructor logic. - Exam focus: UI design with labels/buttons + event handling (e.g., calculator, form validation) and mouse/keyboard event tracing.
1. Swing Basics: Components and Containers
Swing provides lightweight UI components (unlike AWT’s heavyweight peers). Key components:
- Containers:
JFrame(top-level window),JPanel(grouping),JDialog(popups). - Input/Output:
JButton,JTextField,JLabel,JComboBox,JCheckBox. - Specialized:
JTable(data grids),JTree(hierarchical data),JSlider(range inputs).
classDiagram
class JFrame {
+setTitle(String)
+setDefaultCloseOperation(int)
+setSize(int, int)
+setVisible(boolean)
}
class JPanel {
+setLayout(LayoutManager)
+add(Component)
+setBackground(Color)
}
class JButton {
+addActionListener(ActionListener)
+setText(String)
+setIcon(Icon)
}
JFrame "1" --> "contains" JPanel "many"
JPanel "1" --> "contains" JButton "many"
class JLabel {
+setText(String)
+setIcon(Icon)
}
class JTextField {
+setText(String)
+addActionListener(ActionListener)
}
JPanel --> "contains" JLabel
JPanel --> "contains" JTextField
note for JFrame "Top-level window\n(e.g., main app window)"
note for JPanel "Grouping container\n(no window decorations)"
note for JButton "Clickable button\nwith action events"Real-world example:
- eSewa’s payment form uses
JTextFieldfor amount input,JButtonfor "Pay Now," andJLabelfor error messages (e.g., "Insufficient balance"). - Khalti’s checkout employs
JComboBoxfor payment method selection (Khalti Wallet, Bank Transfer, etc.).
Worked Example: Simple Calculator UI
import javax.swing.*;
import java.awt.*;
public class CalculatorUI {
public static void main(String[] args) {
JFrame frame = new JFrame("Calculator");
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(4, 3));
// Add buttons
for (int i = 1; i <= 9; i++) {
frame.add(new JButton(String.valueOf(i)));
}
frame.add(new JButton("0"));
frame.add(new JButton("="));
frame.add(new JButton("+"));
frame.add(new JButton("-"));
frame.add(new JButton("*"));
frame.add(new JButton("/"));
frame.setVisible(true);
}
}
State after setVisible(true):
+--------+--------+--------+
| 1 | 2 | 3 |
+--------+--------+--------+
| 4 | 5 | 6 |
+--------+--------+--------+
| 7 | 8 | 9 |
+--------+--------+--------+
| 0 | = | + |
+--------+--------+--------+
| - | * | / |
+--------+--------+--------+
Key Observations:
GridLayout(4, 3)forces buttons into a 4×3 grid.- Missing
addActionListener()means buttons do nothing yet (exam pitfall!).
2. Layout Managers: Organizing Components
Swing uses layout managers to position components dynamically. Common types:
| Layout Manager | Use Case | Example |
|---|---|---|
BorderLayout |
North/South/East/West/Center | Menus, toolbars |
GridLayout |
Equal-sized grid | Calculator, spreadsheets |
FlowLayout |
Left-to-right, wrap as needed | Forms, labels + text fields |
BoxLayout |
Vertical/horizontal grouping | Multi-line buttons |
Visual: BorderLayout Regions
```figure
{"type":"network","nodes":["North","South","East","West","Center"],"edges":[],"directed":false,"caption":"BorderLayout regions (N=North, S=South, E=East, W=West, C=Center). Components added to regions are stacked vertically/horizontally.","highlight":[["North"],["South"],["East"],["West"],["Center"]]}
**Example: eSewa Login Form**
```java
JFrame frame = new JFrame("eSewa Login");
frame.setLayout(new BorderLayout());
JPanel northPanel = new JPanel();
northPanel.add(new JLabel("Welcome to eSewa"));
frame.add(northPanel, BorderLayout.NORTH);
JPanel centerPanel = new JPanel(new GridLayout(2, 2));
centerPanel.add(new JLabel("Username:"));
centerPanel.add(new JTextField(20));
centerPanel.add(new JLabel("Password:"));
centerPanel.add(new JTextField(20));
frame.add(centerPanel, BorderLayout.CENTER);
frame.add(new JButton("Login"), BorderLayout.SOUTH);
State after adding components:
+---------------------+
| Welcome to eSewa | (NORTH)
+---------------------+
| Username: [______] | (CENTER)
| Password: [______] |
+---------------------+
| Login | (SOUTH)
+---------------------+
3. Event Handling: Responding to User Actions
Swing is event-driven: components trigger events (e.g., ActionEvent for button clicks) that listeners handle.
Common Listeners
| Listener Interface | Event Type | Key Method(s) |
|---|---|---|
ActionListener |
Button clicks, menu items | actionPerformed(ActionEvent) |
MouseListener |
Mouse clicks/moves | mouseClicked(MouseEvent) |
KeyListener |
Key presses | keyPressed(KeyEvent) |
ItemListener |
ComboBox/Checkbox changes | itemStateChanged(ItemEvent) |
Visual: Event Flow
flowchart TD
A["User Clicks Button"] --> B["Button fires ActionEvent"]
B --> C["Event dispatched to ActionListener"]
C --> D["actionPerformed() called"]
D --> E["Update UI or logic"]Worked Example: Calculator with Events
public class CalculatorApp {
private JTextField display;
private double num1 = 0, num2 = 0;
private String operation = "";
public CalculatorApp() {
JFrame frame = new JFrame("Calculator");
display = new JTextField(10);
frame.add(display, BorderLayout.NORTH);
JPanel buttonPanel = new JPanel(new GridLayout(4, 3));
JButton btn7 = new JButton("7");
btn7.addActionListener(e -> display.setText(display.getText() + "7"));
buttonPanel.add(btn7);
// Add other buttons similarly...
frame.add(buttonPanel);
frame.setVisible(true);
}
public static void main(String[] args) {
new CalculatorApp();
}
}
Trace: Clicking "7"
| Step | Action | display Text |
num1/num2 |
operation |
|---|---|---|---|---|
| 1 | Initial state | (empty) | 0/0 | "" |
| 2 | Click "7" | "7" | 0/0 | "" |
Real-world tie-in:
- Pathao’s ride request: Clicking "Request Ride" fires an
ActionEventthat validates input (e.g.,JTextFieldfor pickup location) and calls the backend API.
4. Mouse and Keyboard Events
MouseListener Example: Drawing App
public class DrawingApp extends JFrame {
private JPanel drawPanel = new JPanel();
public DrawingApp() {
setSize(400, 400);
drawPanel.setBackground(Color.WHITE);
add(drawPanel);
drawPanel.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
Graphics g = drawPanel.getGraphics();
g.setColor(Color.RED);
g.fillOval(e.getX(), e.getY(), 5, 5);
}
});
}
public static void main(String[] args) {
new DrawingApp().setVisible(true);
}
}
State after dragging mouse:
KeyListener Example: Password Strength Meter
JTextField passwordField = new JTextField(20);
passwordField.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
String password = passwordField.getText();
if (password.length() >= 8) {
passwordField.setBackground(Color.GREEN);
} else {
passwordField.setBackground(Color.RED);
}
}
});
Trace: Typing "abc12345"
| Key Pressed | Field Text | Background Color |
|---|---|---|
| 'a' | "a" | RED |
| 'b' | "ab" | RED |
| ... | ... | ... |
| '5' | "abc12345" | GREEN |
Real-world example:
- Khalti’s OTP input: Uses
KeyListenerto auto-focus the next field when digits are entered (e.g., typing "123" moves cursor to the 4th OTP box).
5. JavaFX vs. Swing: Key Differences
| Feature | Swing | JavaFX |
|---|---|---|
| Rendering | AWT-based (heavyweight) | Hardware-accelerated (lightweight) |
| Styling | Limited (UIManager) | CSS support |
| Multimedia | Poor support | Built-in (MediaPlayer) |
| Learning Curve | Steeper (manual layout) | Easier (Scene Builder) |
| Use Case | Legacy apps, desktop tools | Modern UIs, mobile (via Gluon) |
Visual: JavaFX Scene Graph
classDiagram
class Scene {
+setRoot(Node)
+setWidth(double)
+setHeight(double)
}
class ParentNode {
<<abstract>>
+getChildren()
+addChild(Node)
}
class Region {
+setStyle(String)
+setPadding(Insets)
}
class Button {
+setOnAction(EventHandler)
+setText(String)
}
class MediaPlayer {
+play()
+stop()
}
Scene "1" --> "contains" ParentNode "many"
ParentNode <|-- Region
ParentNode <|-- Button
Scene --> MediaPlayer
note for Scene "Root container\n(holds all UI elements)"
note for Region "Stylable container\n(e.g., VBox, HBox)"
note for Button "Event-driven\n(uses EventHandler)"Exam Tip:
- Swing is still tested in TU exams (e.g., "Design a form with validation").
- JavaFX may appear in practicals but focus on Swing for theory.
6. Common Exam Patterns and Solutions
Pattern 1: Calculator UI with Buttons
Question: Create a UI with 2 JTextFields (for numbers) and 4 buttons (Add/Subtract/Multiply/Divide) that update a result field.
Solution:
JTextField num1Field = new JTextField(10);
JTextField num2Field = new JTextField(10);
JTextField resultField = new JTextField(10);
JButton addBtn = new JButton("Add");
addBtn.addActionListener(e -> {
double num1 = Double.parseDouble(num1Field.getText());
double num2 = Double.parseDouble(num2Field.getText());
resultField.setText(String.valueOf(num1 + num2));
});
Pattern 2: Mouse Event Tracing
Question: What is the output if you click and drag in this app?
drawPanel.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
System.out.println("Pressed at: " + e.getX());
}
public void mouseReleased(MouseEvent e) {
System.out.println("Released at: " + e.getY());
}
});
Answer:
Pressed at: [X-coordinate]
Released at: [Y-coordinate]
Note: mouseDragged() is not overridden here, so only press/release events fire.
In the Real World
eSewa’s Bill Payment
- Idea Used:
ActionListeneron the "Pay" button validates input (e.g.,JTextFieldfor amount) and triggers a backend call. - How: The button’s
actionPerformed()checks if the amount field is empty or non-numeric before proceeding.
- Idea Used:
Khalti’s Checkout Flow
- Idea Used:
ItemListeneron the payment methodJComboBox(Khalti Wallet/Bank Transfer) dynamically updates fee calculations. - How: Changing the selection fires
itemStateChanged(), which recalculates total amount displayed in aJLabel.
- Idea Used:
NTC’s Service Request Portal (Hypothetical)
- Idea Used:
KeyListeneron the complaint descriptionJTextAreato show a character counter (e.g., "200/500 characters"). - How:
keyTyped()increments a counter label, turning red if the limit is exceeded.
- Idea Used:
Pathao Driver App
- Idea Used:
MouseListeneron the map to detect ride requests (e.g., tapping a location to set pickup/dropoff points). - How:
mouseClicked()validates the tap coordinates before showing a confirmation dialog.
- Idea Used:
Exam Tip
UI Design Questions:
- Always use a layout manager (never absolute positioning).
- Place
add(component)beforesetVisible(true). - For calculators/forms, use
GridLayoutorBorderLayout.
Event Handling:
- ActionListener: For buttons, menu items.
- MouseListener: For clicks/drags (e.g., drawing apps).
- KeyListener: For text input validation (e.g., OTP fields).
- Trace events step-by-step: Show the state of fields/labels after each user action.
Common Mistakes to Avoid:
- Forgetting to add listeners to components.
- Using
nulllayout (exam markers deduct for hardcoded positions). - Not handling
NumberFormatExceptionwhen parsingJTextFieldinput.
Code Structure:
- Declare components as instance variables (not locals) if they need to be accessed by listeners.
- Use lambda expressions for concise listener code (e.g.,
button.addActionListener(e -> ...)).
Practical Exam Advice:
- If asked to "design a UI," sketch the layout first (e.g., "BorderLayout with North=title, Center=grid of buttons").
- For event tracing, create a table like the calculator example above to show variable states.
Final Visual: Full Calculator UI with Events
flowchart TD
A[JFrame
(GridLayout 4x4)] --> B[Display
(JTextField, top-left)]
A --> C[Buttons
(JButton x13, grid)]
C --> D[ActionListener
for digits 0-9]
D --> E["Append digit to display"]
C --> F[ActionListener
for operators +-*/]
F --> G["Store num1/operation"]
C --> H[ActionListener
for =]
H --> I[Calculate result
Update display]
C --> J[ActionListener
for C (clear)]
J --> K[Reset display
Clear memory]Based on the TU BIT syllabus for Advanced Java Programming (BIT401), unit 4.
Discussion
Loading…