M11 Java Paint App Session 2
Aaron Hernandez Jimenez
26 may 2025
Group 131
added extra:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
public class PaintApp extends JFrame {
private DrawingPanel drawingPanel;
private JPanel toolPanel;
private JPanel colorPanel;
private ButtonGroup toolGroup;
private Color currentColor = Color.BLACK;
private Color backgroundColor = Color.WHITE;
private String currentTool = "PENCIL";
// Predefined colors
private final Color[] colors = {
Color.BLACK, Color.RED, Color.BLUE, Color.GREEN, Color.YELLOW,
Color.ORANGE, Color.PINK, Color.CYAN, Color.MAGENTA,
Color.GRAY
};
public PaintApp() {
setTitle("Paint Application - Session 2");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
initializeComponents();
setupLayout();
setSize(800, 600);
setLocationRelativeTo(null);
setVisible(true);
}
private void initializeComponents() {
// Initialize drawing panel
drawingPanel = new DrawingPanel();
// Initialize tool panel
toolPanel = new JPanel();
toolPanel.setLayout(new FlowLayout());
toolPanel.setBackground(Color.LIGHT_GRAY);
// Initialize color panel
colorPanel = new JPanel();
colorPanel.setLayout(new FlowLayout());
colorPanel.setBackground(Color.LIGHT_GRAY);
// Create tool buttons
createToolButtons();
// Create color buttons
createColorButtons();
}
private void createToolButtons() {
toolGroup = new ButtonGroup();
// Pencil tool
JToggleButton pencilBtn = new JToggleButton("Pencil");
pencilBtn.setSelected(true);
pencilBtn.addActionListener(e -> currentTool = "PENCIL");
toolGroup.add(pencilBtn);
toolPanel.add(pencilBtn);
// Rectangle tool
JToggleButton rectangleBtn = new JToggleButton("Rectangle");
rectangleBtn.addActionListener(e -> currentTool = "RECTANGLE");
toolGroup.add(rectangleBtn);
toolPanel.add(rectangleBtn);
// Oval tool - IMPLEMENTED
JToggleButton ovalBtn = new JToggleButton("Oval");
ovalBtn.addActionListener(e -> currentTool = "OVAL");
toolGroup.add(ovalBtn);
toolPanel.add(ovalBtn);
// Eraser tool - IMPLEMENTED (draws with background color)
JToggleButton eraserBtn = new JToggleButton("Eraser");
eraserBtn.addActionListener(e -> currentTool = "ERASER");
toolGroup.add(eraserBtn);
toolPanel.add(eraserBtn);
// Clear button - CHANGED from Arc to Clear, now JButton (not
JToggleButton)
JButton clearBtn = new JButton("Clear");
clearBtn.addActionListener(e -> drawingPanel.clearCanvas());
// Note: clearBtn is NOT added to toolGroup (not part of
ButtonGroup)
toolPanel.add(clearBtn);
}
private void createColorButtons() {
for (Color color : colors) {
JButton colorBtn = new JButton();
colorBtn.setBackground(color);
colorBtn.setPreferredSize(new Dimension(30, 30));
colorBtn.addActionListener(e -> currentColor = color);
colorBtn.setBorder(BorderFactory.createRaisedBevelBorder());
colorPanel.add(colorBtn);
}
}
private void setupLayout() {
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.add(toolPanel, BorderLayout.NORTH);
topPanel.add(colorPanel, BorderLayout.SOUTH);
add(topPanel, BorderLayout.NORTH);
add(new JScrollPane(drawingPanel), BorderLayout.CENTER);
}
// Inner class for the drawing panel
private class DrawingPanel extends JPanel {
private BufferedImage canvas;
private Graphics2D g2d;
private Point startPoint;
private Point endPoint;
private boolean isDrawing = false;
private List<DrawingAction> drawingActions;
public DrawingPanel() {
setPreferredSize(new Dimension(800, 600));
setBackground(backgroundColor);
drawingActions = new ArrayList<>();
// Initialize canvas
canvas = new BufferedImage(800, 600,
BufferedImage.TYPE_INT_RGB);
g2d = canvas.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(backgroundColor);
g2d.fillRect(0, 0, 800, 600);
addMouseListeners();
}
private void addMouseListeners() {
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
startPoint = e.getPoint();
isDrawing = true;
// For pencil and eraser, start drawing immediately
if (currentTool.equals("PENCIL") ||
currentTool.equals("ERASER")) {
drawPoint(e.getPoint());
repaint();
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (isDrawing) {
endPoint = e.getPoint();
switch (currentTool) {
case "RECTANGLE":
drawRectangle();
break;
case "OVAL":
drawOval(); // IMPLEMENTED
break;
}
isDrawing = false;
repaint();
}
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
if (isDrawing && (currentTool.equals("PENCIL") ||
currentTool.equals("ERASER"))) {
drawLine(startPoint, e.getPoint());
startPoint = e.getPoint();
repaint();
}
}
});
}
private void drawPoint(Point point) {
// ERASER IMPLEMENTATION: Use background color for eraser
Color drawColor = currentTool.equals("ERASER") ?
backgroundColor : currentColor;
float strokeWidth = currentTool.equals("ERASER") ? 8.0f :
2.0f;
g2d.setColor(drawColor);
g2d.setStroke(new BasicStroke(strokeWidth,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2d.fillOval(point.x - (int) (strokeWidth / 2), point.y -
(int) (strokeWidth / 2),
(int) strokeWidth, (int) strokeWidth);
}
private void drawLine(Point start, Point end) {
// ERASER IMPLEMENTATION: Use background color for eraser
Color drawColor = currentTool.equals("ERASER") ?
backgroundColor : currentColor;
float strokeWidth = currentTool.equals("ERASER") ? 8.0f :
2.0f;
g2d.setColor(drawColor);
g2d.setStroke(new BasicStroke(strokeWidth,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2d.drawLine(start.x, start.y, end.x, end.y);
}
private void drawRectangle() {
g2d.setColor(currentColor);
g2d.setStroke(new BasicStroke(2.0f));
int x = Math.min(startPoint.x, endPoint.x);
int y = Math.min(startPoint.y, endPoint.y);
int width = Math.abs(endPoint.x - startPoint.x);
int height = Math.abs(endPoint.y - startPoint.y);
g2d.drawRect(x, y, width, height);
}
// OVAL IMPLEMENTATION: Draw oval shapes
private void drawOval() {
g2d.setColor(currentColor);
g2d.setStroke(new BasicStroke(2.0f));
int x = Math.min(startPoint.x, endPoint.x);
int y = Math.min(startPoint.y, endPoint.y);
int width = Math.abs(endPoint.x - startPoint.x);
int height = Math.abs(endPoint.y - startPoint.y);
g2d.drawOval(x, y, width, height);
}
// CLEAR IMPLEMENTATION: Clear all drawn shapes
public void clearCanvas() {
g2d.setColor(backgroundColor);
g2d.fillRect(0, 0, getWidth(), getHeight());
drawingActions.clear(); // Clear the action history as well
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(canvas, 0, 0, null);
}
}
// Helper class for storing drawing actions (for future undo/redo
functionality)
private static class DrawingAction {
String tool;
Color color;
Point start;
Point end;
public DrawingAction(String tool, Color color, Point start, Point
end) {
this.tool = tool;
this.color = color;
this.start = start;
this.end = end;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new PaintApp());
}
}