Lab Manual IX · CSE 202
GUI Components, Drawing, AWT & Swing
Build a Swing drawing application: a JFrame with layout managers, buttons and a colour box, event listeners, and a custom JPanel that draws rectangles and circles with Graphics.
← → move between slides · F full screen · M slide list
Before we start
Why this lab
Every desktop app is a window full of boxes that react to clicks. How does Java put a button on screen and know when it is pressed?
Swing gives you components (JFrame, JButton…), layout managers to arrange them and listeners that run your code on each click. You will build a small paint program.
Lab 9 of 10
Lab at a glance
After this lab you can
- Explain the purpose of GUIs and distinguish AWT from Swing
- Use JFrame, JPanel, JButton, JLabel, JTextField and JComboBox
- Arrange components with BorderLayout, FlowLayout and GridLayout
- Handle events with ActionListener
- Draw shapes by overriding
paintComponent()and using Graphics - Start Swing safely on the Event Dispatch Thread
Before you start
- Labs 4–5: inheritance, abstract classes, overriding
- Lab 7: threads (for the EDT idea)
- ArrayList basics
Plan for the session
- Theory recap
- Walk through the program, section by section, and run it
- In-lab tasks, shown to the instructor
- Report exercises at home
Lab 9 of 10
Contents
Select a part to jump to it.
Theory 1 of 6
AWT, Swing and applets
- AWT is the original toolkit using native OS components; Swing is built on it with lightweight, platform-independent components whose names start with J.
- Applets ran inside browsers; browsers no longer support them, so this lab uses a
JFramedesktop app — the drawing and event ideas are the same.
Theory 2 of 6
Components and containers
- A container holds components: the JFrame holds panels, panels hold buttons, labels and the drawing canvas.
Theory 3 of 6
Layout managers
- BorderLayout: NORTH, SOUTH, EAST, WEST, CENTER. FlowLayout: left to right. GridLayout: equal cells in rows and columns.
Layout managers
JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEFT));
buttons.add(new JButton("Add Rectangle"));
mainPanel.add(drawingPanel, BorderLayout.CENTER);
Theory 4 of 6
Event handling
rectangleButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
drawingPanel.addRectangle(x, y, 100, 80);
updateStatus();
}
});- GUI programs are event-driven: Swing calls
actionPerformedwhen the button is clicked.
Theory 5 of 6
Custom drawing and repaint()
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); // clear the background first
for (Shape shape : shapes) {
shape.draw(g); // polymorphic draw
}
}- Graphics offers drawLine, drawRect, fillRect, drawOval, fillOval, drawString.
- Change the data, then call
repaint(); Swing calls paintComponent for you. Never call it yourself.
Theory 6 of 6
The Event Dispatch Thread
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() { new DrawingApp(); }
});- Swing is not thread-safe: create and update components only on the EDT.
Implementation design
Program design
Implementation design
Execution flow
- main schedules GUI creation on the EDT
- DrawingApp builds the window: title (NORTH), canvas (CENTER), controls and status (SOUTH)
- Listeners are registered on the three buttons
- Add Rectangle / Add Circle: set colour, add a shape, repaint, update status
- Clear All: empty the list and repaint
- Closing the window ends the program
Layout (DrawingApp), drawing (DrawingPanel) and shape behaviour (Shape subclasses) are separate, so adding a TriangleShape is easy.
Code walkthrough 1 of 10 · Shape.java
An abstract drawable shape
public abstract class Shape {
protected int x;
protected int y;
protected Color colour;
public Shape(int x, int y, Color colour) {
this.x = x;
this.y = y;
this.colour = colour;
}
public abstract void draw(Graphics g);
}- Position and colour for every shape; each subclass decides how to draw.
Code walkthrough 2 of 10 · RectangleShape.java
RectangleShape.draw()
@Override
public void draw(Graphics g) {
g.setColor(colour);
g.fillRect(x, y, width, height);
g.setColor(Color.BLACK);
g.drawRect(x, y, width, height);
}- Fill in the shape’s colour, then outline in black.
Code walkthrough 3 of 10 · CircleShape.java
CircleShape.draw()
@Override
public void draw(Graphics g) {
int diameter = 2 * radius;
g.setColor(colour);
g.fillOval(x - radius, y - radius, diameter, diameter);
g.setColor(Color.BLACK);
g.drawOval(x - radius, y - radius, diameter, diameter);
}- fillOval takes the top-left corner, so subtract the radius from the centre.
Code walkthrough 4 of 10 · DrawingPanel.java
paintComponent draws the frame
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawGrid(g);
for (Shape shape : shapes) {
shape.draw(g);
}
}
private void drawGrid(Graphics g) {
g.setColor(new Color(220, 220, 220));
for (int x = 0; x < getWidth(); x += 50) {
g.drawLine(x, 0, x, getHeight());
}
for (int y = 0; y < getHeight(); y += 50) {
g.drawLine(0, y, getWidth(), y);
}
}- Clear, draw the grid, then call draw(g) on every shape (polymorphism).
Code walkthrough 5 of 10 · DrawingPanel.java
Changing the picture
public void addRectangle(int x, int y, int width, int height) {
shapes.add(new RectangleShape(x, y, width, height, currentColor));
repaint();
}
public void addCircle(int x, int y, int radius) {
shapes.add(new CircleShape(x, y, radius, currentColor));
repaint();
}
public void clear() {
shapes.clear();
repaint();
}- Change the list, then
repaint(); never call paintComponent yourself.
Code walkthrough 6 of 10 · DrawingApp.java
Building the window: north and centre
private void setupUI() {
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JLabel titleLabel = new JLabel("Drawing Application");
titleLabel.setFont(new Font("Arial", Font.BOLD, 16));
topPanel.add(titleLabel);
drawingPanel = new DrawingPanel();
drawingPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));- BorderLayout for the frame, FlowLayout for the title row.
Code walkthrough 7 of 10 · DrawingApp.java
Building the window: the controls
JPanel controlPanel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JLabel colorLabel = new JLabel("Colour:");
colorComboBox = new JComboBox<String>(
new String[] {"Blue", "Red", "Green", "Yellow", "Orange", "Purple"});
rectangleButton = new JButton("Add Rectangle");
circleButton = new JButton("Add Circle");
clearButton = new JButton("Clear All");
buttonPanel.add(colorLabel);
buttonPanel.add(colorComboBox);
buttonPanel.add(rectangleButton);
buttonPanel.add(circleButton);
buttonPanel.add(clearButton);- Create each component, then add it to a FlowLayout row.
Code walkthrough 8 of 10 · DrawingApp.java
Placing the panels
statusLabel = new JLabel("Ready. Shapes: 0");
controlPanel.add(buttonPanel, BorderLayout.CENTER);
controlPanel.add(statusLabel, BorderLayout.SOUTH);
mainPanel.add(topPanel, BorderLayout.NORTH);
mainPanel.add(drawingPanel, BorderLayout.CENTER);
mainPanel.add(controlPanel, BorderLayout.SOUTH);
setContentPane(mainPanel);- Panels nest: the button row and status go in controlPanel, which goes in SOUTH.
Code walkthrough 9 of 10 · DrawingApp.java
Responding to clicks
private void addActionListeners() {
rectangleButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
drawingPanel.setCurrentColor(getSelectedColor());
int x = (int) (Math.random() * 600);
int y = (int) (Math.random() * 350);
drawingPanel.addRectangle(x, y, 100, 80);
updateStatus();
}
});- actionPerformed runs on each click: pick the colour, add a shape, update the label.
Code walkthrough 10 of 10 · Lab9Demo.java
Starting on the Event Dispatch Thread
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new DrawingApp();
}
});
}- invokeLater runs the GUI code on Swing’s own thread.
Step through the code · 1 of 2
Trace: change the model, then repaint()
Each click adds a shape to the list; paintComponent draws whatever is in the list.
Step through the code · 1 of 2
Trace: change the model, then repaint() (cont.)
Step through the code · 2 of 2
Trace: main, the EDT and a click
invokeLater hands the work to the Event Dispatch Thread. Every listener and every paint then runs on that one thread.
Step through the code · 2 of 2
Trace: main, the EDT and a click (cont.)
For reference · 6 files
The complete program
import java.awt.Color;
import java.awt.Graphics;
public abstract class Shape {
protected int x;
protected int y;
protected Color colour;
public Shape(int x, int y, Color colour) {
this.x = x;
this.y = y;
this.colour = colour;
}
public abstract void draw(Graphics g);
}import java.awt.Color;
import java.awt.Graphics;
public class RectangleShape extends Shape {
private int width;
private int height;
public RectangleShape(int x, int y, int width, int height, Color colour) {
super(x, y, colour);
this.width = (width > 0) ? width : 100;
this.height = (height > 0) ? height : 80;
}
@Override
public void draw(Graphics g) {
g.setColor(colour);
g.fillRect(x, y, width, height);
g.setColor(Color.BLACK);
g.drawRect(x, y, width, height);
}
}import java.awt.Color;
import java.awt.Graphics;
public class CircleShape extends Shape {
private int radius;
public CircleShape(int x, int y, int radius, Color colour) {
super(x, y, colour);
this.radius = (radius > 0) ? radius : 50;
}
@Override
public void draw(Graphics g) {
int diameter = 2 * radius;
g.setColor(colour);
g.fillOval(x - radius, y - radius, diameter, diameter);
g.setColor(Color.BLACK);
g.drawOval(x - radius, y - radius, diameter, diameter);
}
}import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
public class DrawingPanel extends JPanel {
private ArrayList<Shape> shapes;
private Color currentColor;
public DrawingPanel() {
shapes = new ArrayList<Shape>();
currentColor = Color.BLUE;
setBackground(Color.WHITE);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
drawGrid(g);
for (Shape shape : shapes) {
shape.draw(g);
}
}
private void drawGrid(Graphics g) {
g.setColor(new Color(220, 220, 220));
for (int x = 0; x < getWidth(); x += 50) {
g.drawLine(x, 0, x, getHeight());
}
for (int y = 0; y < getHeight(); y += 50) {
g.drawLine(0, y, getWidth(), y);
}
}
public void addRectangle(int x, int y, int width, int height) {
shapes.add(new RectangleShape(x, y, width, height, currentColor));
repaint();
}
public void addCircle(int x, int y, int radius) {
shapes.add(new CircleShape(x, y, radius, currentColor));
repaint();
}
public void clear() {
shapes.clear();
repaint();
}
public void setCurrentColor(Color colour) {
this.currentColor = colour;
}
public int getShapeCount() {
return shapes.size();
}
}import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class DrawingApp extends JFrame {
private DrawingPanel drawingPanel;
private JLabel statusLabel;
private JButton rectangleButton;
private JButton circleButton;
private JButton clearButton;
private JComboBox<String> colorComboBox;
public DrawingApp() {
setTitle("Drawing Application");
setSize(800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setupUI();
addActionListeners();
setVisible(true);
}
private void setupUI() {
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JLabel titleLabel = new JLabel("Drawing Application");
titleLabel.setFont(new Font("Arial", Font.BOLD, 16));
topPanel.add(titleLabel);
drawingPanel = new DrawingPanel();
drawingPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2));
JPanel controlPanel = new JPanel(new BorderLayout());
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JLabel colorLabel = new JLabel("Colour:");
colorComboBox = new JComboBox<String>(
new String[] {"Blue", "Red", "Green", "Yellow", "Orange", "Purple"});
rectangleButton = new JButton("Add Rectangle");
circleButton = new JButton("Add Circle");
clearButton = new JButton("Clear All");
buttonPanel.add(colorLabel);
buttonPanel.add(colorComboBox);
buttonPanel.add(rectangleButton);
buttonPanel.add(circleButton);
buttonPanel.add(clearButton);
statusLabel = new JLabel("Ready. Shapes: 0");
controlPanel.add(buttonPanel, BorderLayout.CENTER);
controlPanel.add(statusLabel, BorderLayout.SOUTH);
mainPanel.add(topPanel, BorderLayout.NORTH);
mainPanel.add(drawingPanel, BorderLayout.CENTER);
mainPanel.add(controlPanel, BorderLayout.SOUTH);
setContentPane(mainPanel);
}
private void addActionListeners() {
rectangleButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
drawingPanel.setCurrentColor(getSelectedColor());
int x = (int) (Math.random() * 600);
int y = (int) (Math.random() * 350);
drawingPanel.addRectangle(x, y, 100, 80);
updateStatus();
}
});
circleButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
drawingPanel.setCurrentColor(getSelectedColor());
int x = 60 + (int) (Math.random() * 600);
int y = 60 + (int) (Math.random() * 350);
drawingPanel.addCircle(x, y, 50);
updateStatus();
}
});
clearButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
drawingPanel.clear();
updateStatus();
}
});
}
private Color getSelectedColor() {
String selected = (String) colorComboBox.getSelectedItem();
if ("Red".equals(selected)) {
return Color.RED;
} else if ("Green".equals(selected)) {
return Color.GREEN;
} else if ("Yellow".equals(selected)) {
return Color.YELLOW;
} else if ("Orange".equals(selected)) {
return new Color(255, 165, 0);
} else if ("Purple".equals(selected)) {
return new Color(128, 0, 128);
} else {
return Color.BLUE;
}
}
private void updateStatus() {
statusLabel.setText("Ready. Shapes: " + drawingPanel.getShapeCount());
}
}import javax.swing.SwingUtilities;
public class Lab9Demo {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new DrawingApp();
}
});
}
}Copy or download each file, save it under the same name, then compile and run: javac *.java → java Lab9Demo
Implementation
Expected output
The program opens a window instead of printing to the console. When it works you should see:
- A window titled “Drawing Application” with a white canvas and a light grey grid
- A colour box and Add Rectangle, Add Circle and Clear All buttons
- Each Add button draws a filled shape in the selected colour at a random position
- Clear All empties the canvas
- The status label shows the current number of shapes
Interactive
Try the drawing application
Interactive 1 of 2
Explore layout managers
Interactive 2 of 2
Drawing with Graphics calls
In-lab task 1 of 3
Task 1: Add a TriangleShape
Show a hint
g.fillPolygon(xs, ys, 3) and g.drawPolygon(xs, ys, 3) with two int arrays.In-lab task 2 of 3
Task 2: Mouse-click drawing
Show a hint
MouseAdapter and override only mouseClicked(MouseEvent e); read e.getX(), e.getY().In-lab task 3 of 3
Task 3: Colour picker
Show a hint
JColorChooser.showDialog(this, "Pick a colour", current) returns null if the user cancels.In-lab tasks
Show your work during the lab
For each task, show the instructor:
- the source code
- a successful compilation
- the running output
- a short explanation of the logic you used
Lab report · exercise 1 of 2
Undo and redo
Lab report · exercise 2 of 2
Freehand drawing with mouse drag
Lab report
Writing the lab report
- Problem statement and your design (classes, fields, methods)
- Complete source code, formatted and commented
- Sample output or screenshots for normal and edge cases
- A short discussion: what each OOP concept did in your program
Academic integrity
Copying from the internet, classmates, seniors or any other unauthorized source is strictly prohibited. Full marks may be deducted if plagiarism, copied work or academic dishonesty is detected. Complete the tasks, implementation, output analysis and report yourself.
Discussion and analysis
Viva questions (1 of 2)
super.paintComponent(g) first?Show the answer
Show the answer
Discussion and analysis
Viva questions (2 of 2)
Show the answer
Show the answer
Check yourself
Quiz
Summary
Summary
- Swing builds on AWT with lightweight J-components; applets are obsolete.
- Containers hold components; layout managers position them.
- Listeners make the GUI event-driven.
- Draw in paintComponent and trigger it with repaint().
- Create and update Swing on the Event Dispatch Thread.