Pretty much I create a Shape class, with Rectangle, Circle, Triangle extending Shape, and a Square class extending Circle. I have the code working with this main class, but I'm having a tough time converting it into GUI because I'm not sure how to do number 3 to make this come together and how to make a g.drawOval(with given x,y & radius) and draw triangle(given x,y, base and height).
Project6 class will have to extend the JFrame class
Project6 constructor will have to set up the GUI window.
A new abstract method: public void display(Graphics g); should be added to the base and derived classes.
A custom JPanel must be set up with a paintComponent method
The new display(Graphics g) method will have to draw the shapes on the GUI window and be called from a loop in the paintComponent method.
import javax.swing.*;
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Project6 extends JFrame {
private Shape [] thearray = new Shape[100];
public static void main (String [] args) {
Project6 tpo = new Project6();
tpo.run();
}
public void run () {
int count = 0;
thearray[count++] = new Circle(20, 20, 40);
thearray[count++] = new Triangle(70, 70, 20, 30);
thearray[count++] = new Rectangle(150, 150, 40, 40);
thearray[count++] = new Square(100, 100, 50, 75);
for (int i = 0; i < count; i ++ ) {
thearray[i].display();
}
int offset = 0;
double totalarea = 0.0;
while (thearray[offset] != null) {
totalarea = totalarea + thearray[offset].area();
offset++;
}
System.out.println("The total area for " + offset + " Shape objects is " + totalarea);
}
public Project6() {
JFrame frame = new JFrame();
frame.setSize(800, 700);
frame.setTitle("Shapes: Circle, Triangle, Rectangle, Square");
frame.setLocationRelativeTo(null); //Center Frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static class MyPanel extends JPanel {
public static JPanel showJPanel(Graphics g) {
panel = new MyPanel();
return panel;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for(int i = 0; i < thearray.length && thearray[i] != null; i++) {
thearray[i].display();
Do I add something like this at the end of each of my classes? I.E. Circle, Square, Triangle, Rectangle class?
#Override
public void draw(Graphics g) {
g.drawRect(getXPos(), getYPos(), width, height);
}
I can't change the way the array is set up, but isn't this supposed to be the class that extends JFrame?
public Project6() {
JFrame frame = new JFrame();
frame.setSize(800, 700);
frame.setTitle("Shapes: Circle, Triangle, Rectangle, Square");
frame.setLocationRelativeTo(null); //Center Frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
I'm new to GUI so this is a little hard to do, but would this work for drawing the shapes? But I get an error saying nonstatic method get() cant be referenced from static context
class NewPanel extends JPanel {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(Triangle.getXPos(), 0, 0, Triangle.getYPos());
g.drawLine(Triangle.getXPos(), 0, Triangle.getXPos, Triangle.getYPos());
g.drawLine(Triangle.getXPos(), Triangle.getYPos, 0, Triangle.getYPos());
g.drawRect(Rectangle.getXPos(), Rectangle.getYPos(), Rectangle.getWidth(), Rectangle.getHeight());
g.drawRect(Square.getXPos(), Square.getYPos(), Square.getWidth(), Square.getHeight());
g.drawOval(Circle.getXPos(), Circle.getYPos(), Circle.getRadius(), 10);
for(int i = 0; i < thearray.length && thearray[i] != null; i++) {
thearray[i].display();
}
}
Your class extends a JFrame that is never displayed
You should draw your shapes in the paintComponent method of a JPanel, one that is added to your JFrame.
I would use an ArrayList<Shape>, not an array, since this way I'd be able to add as many or as few Shapes to my collection and not have to worry about null items.
I'd then iterate through the collection in the paintComponent method override and draw each Shape using a Graphics2D object.
Regarding your last question, "Do I add something like this at the end of each of my classes? ie(Circle, square, triangle, rectangle class?..." no, there's no need for a "draw" method since you'll be using the paintComponent method to do your drawing.
Related
I am trying to build a bounce game in Java. My project has three classes ie the Main class which creates a new window(frame) where the game buttons and bounce objects are drawn.
The GameInterface class which represents the properties of the frame being drawn and the RightPanel class which I created so that I could override the paint(Graphics) method to draw my bounce object. So far this is what I have managed to draw with the code.
You can see that I have two JPanels, one that holds my buttons and the other one that accepts the drawing of a round ball on it ie RightPanel
I need help with the Button Event listeners to move the ball up and down and when user holds the button down, it needs to keep moving down until reaches the down order, sam for the up button.
The code am using is provided below.
GameInterface class
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
public class GameInterface extends JFrame {
//we need this panel declaration in the class level for reference from other methods
RightPanel rightpanel;
//define the physical properties of the window
public GameInterface(){
setSize(new Dimension(600, 600));
setResizable(false);
setTitle("Bounce Game");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBackground(Color.black);
//define a new JSplitPane and use it to add two JPanels
JPanel leftpanel= new JPanel();
//add buttons to the left panel programatically
JButton up= new JButton("Move up");
//set the event listeners for the buttons
up.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
//move my ball up
//clear and redraw the ball while in a new position, use a timer or
something
}
});
JButton down = new JButton("Move down");
down.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
//move my ball down
// rightpanel.getGraphics.fillColor(Color.RED);
}
});
leftpanel.add(up);
leftpanel.add(down);
//add a new RightPanel with a drawn red object
rightpanel= new RightPanel();
JSplitPane splitpane= new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,leftpanel,rightpanel);
this.add(splitpane);
setVisible(true);
}
}
RightPanel class
import javax.swing.*;
import java.awt.*;
public class RightPanel extends JPanel {
//define the position where the circle will be drawn
private int positionX=150;
private int positionY=150;
//I had an idea where we need a timer and then on delay we
//decrement positionX by 3 for move down but can't figure out how to clear RightPanel
private int radius=100;//as the shape is a circle
//override the paint method to draw the bounce ball on the second panel
#Override
public void paint(Graphics g) {
g.setColor(Color.RED);
g.fillOval(positionX,positionY,radius,radius);
}
}
Main class
public class Main
{
public static void main(String args[]){
new GameInterface();
}
}
How do I add logic to my code to make it move the circle up an down, Thank You.
I tried using a timer object to clear the panel and then redraw the ball in the new position of the ball but it draws a vertical bar, not clearing the original ball drawn.
Never call getGraphics() on a component.
Override paintComponent not paint
Call the super.paintComponent(g) in your override.
Give the RightPanel class setter methods that allow you to change the positionX and positionY locations for drawing,
In the button listener, call an appropriate setter method, and then call repaint() on on the RightPanel instance after changing the positions.
For example:
The key code below is here in the ActionListener where you update the position values and call repaint:
moveRightBtn.addActionListener(e -> {
// get and update the x position
int x = drawOval.getPositionX();
x += DELTA;
// call the setter method
drawOval.setPositionX(x);
// request that Java repaint the JPanel
drawOval.repaint();
});
and in the drawing JPanel's paintComponent method where you call the super's method and draw the oval:
#Override
protected void paintComponent(Graphics g) {
// this is needed to do house-keeping painting, to clear "dirty" pixels
super.paintComponent(g);
// this is needed to draw smooth graphics
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(OVAL_COLOR);
g2.fillOval(positionX, positionY, RADIUS, RADIUS);
}
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.*;
#SuppressWarnings("serial")
public class MoveCircle extends JPanel {
private static final int DELTA = 5;
private DrawOval drawOval = new DrawOval();
public MoveCircle() {
JButton moveRightBtn = new JButton("Move Right");
moveRightBtn.addActionListener(e -> {
// get and update the x position
int x = drawOval.getPositionX();
x += DELTA;
// call the setter method
drawOval.setPositionX(x);
// request that Java repaint the JPanel
drawOval.repaint();
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(moveRightBtn);
setLayout(new BorderLayout());
add(drawOval);
add(buttonPanel, BorderLayout.LINE_START);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
MoveCircle mainPanel = new MoveCircle();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
#SuppressWarnings("serial")
class DrawOval extends JPanel {
private static final int RADIUS = 100;
private static final int PANEL_WIDTH = 600;
private static final int PANEL_HEIGHT = 450;
private static final Color OVAL_COLOR = Color.RED;
private int positionX = 0;
private int positionY = 0;
public DrawOval() {
setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
}
public int getPositionX() {
return positionX;
}
public void setPositionX(int positionX) {
this.positionX = positionX;
}
public int getPositionY() {
return positionY;
}
public void setPositionY(int positionY) {
this.positionY = positionY;
}
#Override
protected void paintComponent(Graphics g) {
// this is needed to do house-keeping painting, to clear "dirty" pixels
super.paintComponent(g);
// this is needed to draw smooth graphics
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(OVAL_COLOR);
g2.fillOval(positionX, positionY, RADIUS, RADIUS);
}
}
I've been trying to make this work so that there are 20 boxes each with 3 different sizes and 3 different colours that chosen at random, but i cant make them come out at different times and they just glitch into eachother and the colours are glitching together and stuff like that, anyone know how to fix it? Heres what i got so far:
import java.awt.*;
import javax.swing.*;
public class testwork extends JPanel { //JPanel is a class
int l = 0;
private int x = 10;
private int y = 500;
private void move()
{
x++;
}
boolean red = false;
boolean blue = false;
boolean green = false;
#Override
public void paint(Graphics g) { //JPanel is a class defined in
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Color rectColor = new Color(0, 66, 89);
g2d.setColor(rectColor);
//belt
g2d.setColor(Color.lightGray);
g2d.fillRect(0,450,1500,200);
g2d.fillRect(700,0,200,1000);
g2d.setColor(Color.orange);
for (int i = -10000; i<10000; i=i+50) {
int m= i++;
g2d.fillRect(m, 450, 25, 200);
}
g2d.setColor(Color.DARK_GRAY);
g2d.fillRect(700, 450, 200, 200);
//boxes
while (l<=20) {
if (Math.random() < 0.5)
{g2d.setColor(Color.RED);;}
else if (Math.random() < 0.5) {g2d.setColor(Color.GREEN);}
else {g2d.setColor(Color.BLUE);}
if (Math.random() < 0.5)
{g2d.fillRect(x,y,50,50);}
else if (Math.random() < 0.5) {g2d.fillRect(x,y,50,100);}
else {g2d.fillRect(x,y,100,50);}
l++;
}
}
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("Frame"); //Add our JPanel to the frame
frame.add(new attempt());//instantiate a new object
frame.setSize(1500, 1000);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
testwork p = new testwork();
frame.add(p);
while (true)
{
p.move(); //Updates the coordinates
p.repaint();
Thread.sleep(10); //Pauses for a moment
}}
}
Unfortunately, you are doing a number of things incorrectly.
Override paintComponent and not paint.
Don't use Thread.sleep. Use a Swing timer and an ActionListener
You are doing too much in the painting method. All event handling including calls to repaint() is done on the Event Dispatch Thread(EDT). So all your updating are done inside of paintComponent so only the last painted objects will be shown when you exit. Update your coordinates, data structure and anything else that needs to be painted outside of your paint method.
Put your boiler plate code inside your Testwork class constructor. Here is an example.
public Testwork() {
setPreferredSize(new Dimension(1000, 700));
Timer timer = new Timer(0, this);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
// sizes the frame and jpanel and organizes the components.
frame.pack();
// centers the window in the screen
frame.setLocationRelativeTo(null);
// sets the delay in milliseconds
timer.setDelay(100);
// starts the timer
timer.start();
}
Here would be your actionListener code.
public void actionPerformed(ActionEvent ae) {
// update any variables that need to be used int he
// paint routine here. That means if you want to move something
// update the coordinates here and then use them in the paint method.
}
when you start up, your app, do it like this
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Testwork());
}
There is much more to painting. I recommend checking out Custom Painting in the Java tutorials. Here is another example on this (SO) site.
Hi I am trying to get my program to move the shapes I create across the screen and for some reason its not working Im not sure whats happening? It has to be something small can anyone point me in the right direction.
public class MultipleObs extends JFrame {
private JPanel paintPanel;
public MultipleObs() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setMinimumSize(new Dimension(300, 300));
paintPanel = new PaintPanel();
getContentPane().add(paintPanel, BorderLayout.CENTER);
pack();
}
class PaintPanel extends JPanel implements ActionListener {
private java.util.List<Shape> shapes;
private Shape mouseOverShape=null;
int x=0, velX=2;
javax.swing.Timer tm = new javax.swing.Timer(5,this);
public PaintPanel(){
super();
shapes = new ArrayList<Shape>();
shapes.add(new Rectangle2D.Float(x,25,25,25));
shapes.add(new Ellipse2D.Float(x, 15, 60, 30));
shapes.add(new Ellipse2D.Float(x, 35, 60, 30));
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
for (Shape s : shapes){
g2.draw(s);
}
tm.start();
}
#Override
public void actionPerformed(ActionEvent e) {
x = x+ velX;
repaint();
}
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MultipleObs().setVisible(true);
}
});
}
}
Two issues:
Do not ever start a Swing Timer inside of paintComponent. That method should be for painting and painting only. Instead start the Timer in the constructor.
When you create an Ellipse2D object, its position is fixed. Changing one of the variables used to create it will have no effect on the already created object.
A possible solution is to not use Ellipse2D's but instead draw ovals using Graphics#drawOval(...) inside of paintComponent and use the changing x field in that method call. If you must use Ellipse2D's, then you will need to translate them some way, perhaps by using an AffineTransform, but this way is a bit more complicated since I think that you'd have to wrap your Ellipse2D into a Path2D for this to work.
Another option: create a BufferedImage sprite, draw your complex shapes into the BufferedImage using a Graphics2D object obtained from the BufferedImage, and then draw that within paintComponent via drawImage(myImage, imageX, imageY, null), and change the imageX in your Timer.
I'm making a chess game, and I'm using a chessboard that I made with paint at 480x480, and got the pieces from some sprite and made each one of them 60x60 and transparent background. I managed to put the chessboard and the pieces on screen, but the positions are messy. I'm using null layout. I did:
chessBoardLabel.setBounds(0, 0+25, 480, 480);
the +25 is because of the Frame's thing that is on top and looks like it is considered in positioning.
as for the piece, for example:
for (int i = 0; i <= 7; i++)
whitePawnArray[i] = new whitePawnPiece(i*60,420+25);
the parameters set the xPos and yPos. For the bounds function, I did:
whitePawnLabel.setBounds(this.xPos, this.yPos, this.xPos+60, this.yPos+60);
But this happens:
If I do that:
for (int i = 0; i <= 7; i++)
whitePawnArray[i] = new whitePawnPiece(i*40,280+15);
this happens:
First: what happened to the positioning? Why doesn't it follow what I intended it to be?
Second: what is the 8th piece doing in the middle of nowhere?
package chess.game;
import java.util.*;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class chessMain extends JFrame{
public static void main (String arguments[]){
//Create White
whitePiece white_piece = new whitePiece();
whitePawnPiece[] whitePawnArray = new whitePawnPiece[8];
for (int i = 0; i <= 7; i++) whitePawnArray[i] = new whitePawnPiece(i*40,280+15);
/*whiteTowerPiece[] whiteTowerArray = new whiteTowerPiece[2];
whiteTowerArray[0] = new whiteTowerPiece(0,420);
whiteTowerArray[1] = new whiteTowerPiece(420,420);
whiteHorsePiece[] whiteHorseArray = new whiteHorsePiece[2];
whiteBishopPiece[] whiteBishopArray = new whiteBishopPiece[2];
whiteKingPiece whiteKing = new whiteKingPiece();
whiteQueenPiece whiteQueen = new whiteQueenPiece();*/
//Create Black
JFrame frame = new JFrame();
JPanel panel;
//Initialize
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Chess");
frame.setSize (640,640);
frame.setResizable(false);
frame.setLayout(null);
panel = new JPanel();
panel.setLayout(null);
frame.getContentPane().add(panel);
//draw chessBoard
ImageIcon chessBoardIcon = new ImageIcon(frame.getClass().getResource("/chess/art/Chess_Art/chessBoard.png"));
JLabel chessBoardLabel = new JLabel(chessBoardIcon);
panel.add(chessBoardLabel);
chessBoardLabel.setBounds(0, 0+25, 480, 480);
frame.setComponentZOrder(chessBoardLabel, 1);
frame.setComponentZOrder(panel, 2);
//draw Pawn
for (int i = 0; i<=7; i++){
panel.add(whitePawnArray[i].whitePawnLabel);
whitePawnArray[i].draw();
frame.setComponentZOrder(whitePawnArray[i].whitePawnLabel, 0);
}
frame.setVisible(true);
}
}
public class whitePawnPiece extends whitePiece{
JLabel whitePawnLabel;
ImageIcon whitePawnIcon;
public whitePawnPiece(int x, int y){
whitePawnIcon = new ImageIcon(getClass().getResource("/chess/art/Chess_Art/white/whitePawnPiece.png"));
whitePawnLabel = new JLabel (whitePawnIcon);
//whitePawnLabel.setOpaque(true);
this.xPos = x;
this.yPos = y;
//this.draw();
}
#Override
public void move(int newX, int newY){
this.xPos = (newX/60)*60; //calcular nova pos
this.yPos = (newY/60)*60;
this.draw();
}
/*public void possibleMoves(){
selectorMark.drawNew(this.xPos, this.yPos);
selectorMark.drawNew(this.xPos - 60, this.yPos - 60);
if (this.yPos == 420) selectorMark.drawNew(this.xPos - 120, this.yPos - 120);
}*/
#Override
public void draw(){
//whitePawnIcon.paintIcon(null, chessGUI2.getGraphics(), xPos, xPos);
whitePawnLabel.setBounds(this.xPos, this.yPos, this.xPos+60, this.yPos+60); //x, y, width, height
}
}
public class whitePiece{
int xPos, yPos;
public void move(){}
public void draw(){}
}
First time putting whole code hope I edited it right hehe
Don't use CardLayout for this.
I'd use a JPanel that uses GridLayout to hold an 8x8 grid of chess square JPanels.
I'd place that in a JLayeredPane.
I'd add my pieces to the appropriate chess square JPanel.
When moving a piece, I'd lift it up to the drag layer of the JLayeredPane.
Also:
Don't draw directly on to a top-level window such as a JFrame.
Don't override the paint method.
Instead, if you must do drawing, override the paintComponent(Graphics g) of a JPanel or JComponent.
But again, if you create your chess board out of small JPanel chess squares, it is easy and natural to place pieces on the chess square and have it placed well.
For example, please check out my code here.
I am trying to add/draw a single Graphics object to an existing JPanel. I am generating 10 initial Graphics objects randomly sized and place in the panel, but would like to add additional drawn objects one a time, randomly sized and placed like the initial 10.
Currently, the AddNewDrawItem class is not rendering the new Graphics object.
Thank you for input.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class Painter{
private DrawingPanel dp = new DrawingPanel();
//constructor
public Painter(){
buildGUI();
}
private void buildGUI(){
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.setTitle("Paint drawing demonstration");
JPanel headerPanel = new JPanel();
headerPanel.add(new JLabel("The drawing panel is below"));
JButton addNew = new JButton("Add New Graphic");
addNew.addActionListener(new addNewClickHandler());
headerPanel.add(addNew);
frame.add(BorderLayout.NORTH,headerPanel);
frame.add(BorderLayout.SOUTH,this.dp);
frame.pack();
frame.setVisible(true);
}
class DrawingPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.white);
int x, posx, posy, width, height;
for(x=0;x<=10;x++){
//even number differentiation
if(x % 2 == 0){
g.setColor(Color.red);
}else{
g.setColor(Color.blue);
}
Random rand = new Random();
posx = rand.nextInt(300);
posy = rand.nextInt(300);
width = rand.nextInt(40);
height = rand.nextInt(40);
//System.out.println("the ran x pos is: " + posx);
g.fillRect(posx, posy, width, height);
}//end for
}//end paintComponent
public Dimension getPreferredSize() {
return new Dimension(400,400);
}
}// end DrawingPanel
private class addNewClickHandler implements ActionListener{
public void actionPerformed(ActionEvent e){
System.out.print("in addNew_click_handler click handler");//trace debug
AddNewDrawItem newItem = new AddNewDrawItem();
newItem.repaint();
System.out.print("after repaint() in addNew_click_handler click handler");//trace debug
}
}
class AddNewDrawItem extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.white);
int posx, posy, width, height;
Random rand = new Random();
posx = rand.nextInt(300);
posy = rand.nextInt(300);
width = rand.nextInt(40);
height = rand.nextInt(40);
g.setColor(Color.cyan);
g.fillRect(posx, posy, width, height);
}//end paintComponent
}//end AddNewDrawItem
public static void main(String args[]){
new Painter();
}
}//end class Painter
You've got some problems with your code, one of which is that you've got program logic in your paintComponent method: the code randomly changes values that are displayed within this method, meaning your display will change when it repaints, whether you want it to or not. To see that this is so, try to resize your GUI and you'll see some psychedelic changes in the drawn red and blue rectangles.
Now as to your current problem, the solution to it is similar to the solution to the problem I describe above. I suggest...
that you create an ArrayList<Rectangle2D>,
that you create your random rectangles in your class's constructor so that they're created only once, and then place them in the ArrayList above.
that you iterate through this ArrayList in your JPanel's paintComponent method, drawing them as you go. This way paintComponent does nothing but paint which is as it should be,
that you create a MouseAdapter-derived object and add it as a MouseListener and MouseMotionListener to your DrawingPanel
that you use the listener above to create a new Rectangle2D object and when done add it to the ArrayList and call repaint on the DrawingPanel
that you activate the mouse adapter via your button's action listener.
I'll stop there, but I think you get the idea, and if you don't, please ask any questions you may have.