Title: Spots
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

Spots Programs

In this set of notes, we are going to try to provide some insight into the paint routine. To do so, we need to introduce you to the Interfaces associated with Mouse Activity. We will look at Listener interfaces in more detail in a later set of notes. We are going to create a series of simple programs that allow you to click and see spots drawn in the spot where you clicked.

MouseListener Interface -

Think back to how we did the ActionListener Interface and many of the steps are similar:

1. First we need a class which implements the desired Interface which is MouseListener for now. The easiest class to work with is our top level Spots class that is derived from Applet. So we add the claim in defining Spots:
implements MouseListener
2. Now that our class implements an interface, we are obligated to add all of the methods that go with this interface. This interface has 5 methods, which we add even though we only want to work with one of them.
3. We actually put some code into MousePressed. The other 4 routines are empty.
4. We need to tell someone to give us MouseListener calls. We end up telling the Component class that is underneath our Spots derived Applet class. We do this with the call
addMouseListener(this); // pass point to this class
5. In the MousePressed routine we receive an instance of MouseEvent. This class has all of the information available about the mouse activity. What we want to know is the location where the Mouse was pressed. To get this information call the getX, and getY methods on the MouseEvent.
6. We store the location of the mouse press in a global Point variable called clickPoint. This class mostly just stores and x and a y location.
7. Now how do we get the paint routine called. We can't just call paint. To do that we would have to create a Graphics class and we don't have enough system information to do this. Note that the Graphics class is abstract, which means that something in the system needs to fill in some holes.
8. The proper way to do it is to call the repaint() method. This tells the system that we want the system to generate a paint call.

Spots.java


import java.awt.*;
import javax.swing.*;
import java.awt.event.*;


public class Spots extends JFrame
        implements MouseListener{
    Point clickPoint=new Point(-1,-1);
    int radius = 7;

    public Spots(String name)
    {
        super(name);
        this.setSize(800, 400);
        setVisible(true);
		
    // Our JFrame is a Component.  We want to register it to
    // fire MouseEvents according to the MouseListener interface
    // The class which will handle this interface in the JFrame itself.
    // This implies our JFrame must implement the MouseListener interface.

       addMouseListener(this);
    }

    public void paint(Graphics g)
    {
       super.paint(g); // This clears the screen
       // find out how big our drawing area is
       int w = getSize().width;
       int h = getSize().height;
       // Make a red spot
       Color color = new Color(1.0f, 0.0f, 0.0f);

       g.drawRect(0,0,w -1, h -1); // draw boundary

       if (clickPoint.x >= 0)
       {
          g.setColor(color);
          g.fillOval(clickPoint.x - radius,    clickPoint.y - radius,
                    2*radius, 2*radius);
       }
    }
    public void mousePressed(MouseEvent e)
    {
       clickPoint.x = e.getX();
       clickPoint.y = e.getY();
       // Note that nothing happens unless I tell java to repaint my screen
       repaint();
    }

    public void mouseClicked(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}

    public static void main(String[] args) {
        Spots spots = new Spots("My Spots Program");
    } // end of main


}


A Few changes

Consider changing the statement:
Color color = new Color(1.0f, 0.0f, 0.0f);
to:
Color color = new Color( (float)Math.random(), (float)Math.random(), (float)Math.random());

Also consider adding an instance boolean called first which is initialized to true. Then replace:
super.paint(g);
with
if (first)
{
first=false;
super.paint(g);
}

Note that if you minimize and bring and then bring the JFrame back that only the last spot remains.

SpotsSave.java

If we really care about spots being repainted after our window is covered, we need to remember the spots in some collection class.

We create a Helper Data class to store the location of the point and the Color of the spot. Everytime we click, we just store another Data class into our ArrayList class.

We still call repaint and in our paint method we redraw all spots stored in the ArrayList class.




import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;


//Class to save Spot Data
class Data
{
 int x, y;
 Color c;

 Data(int x, int y, Color c1)
 {
     this.x = x;
     this.y = y;
     c=c1;
 }
}

public class SpotsSave extends JFrame
        implements MouseListener{
    int radius = 7;
    ArrayList arrsave = new ArrayList();

    public SpotsSave(String name)
    {
        super(name);
        this.setSize(800, 400);
        setVisible(true);

    // Our JFrame is a Component.  We want to register it to
    // fire MouseEvents according to the MouseListener interface
    // The class which will handle this interface in the JFrame itself.
    // This implies our JFrame must implement the MouseListener interface.

       addMouseListener(this);
    }

    public void paint(Graphics g)
    {

       super.paint(g);

       int w = getSize().width;
       int h = getSize().height;

       g.drawRect(0,0,w -1, h -1); // draw boundary

       // Paint all spots
       for (int i=0; i < arrsave.size(); i++)
       {
           Data d = (Data)arrsave.get(i);
           g.setColor(d.c);
           g.fillOval(d.x - radius,    d.y - radius,
                       2*radius, 2*radius);
       }
    }
    public void mousePressed(MouseEvent e)
    {
       int x = e.getX();
       int y = e.getY();

       Color color = new Color(
            (float)Math.random(), (float)Math.random(), (float)Math.random());
       Data d = new Data(x, y, color);

       // Add a new Spot to the Data collection
       arrsave.add(d);
       // Note that nothing happens unless I tell java to repaint my screen
       repaint();
    }

    public void mouseClicked(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}

    public static void main(String[] args) {
        SpotsSave spots = new SpotsSave("My Spots Save Program");
    } // end of main


}





Cover artwork and then uncover artwork

SpotsArt.java

More for fun than anything else, we want to add another Interface. We want to be able to drag our mouse and get a brush effect. Note that we have removed the Vector class that stored our Data, so we won't be able to redraw our screen after it is covered.

Adding the MouseMotionListener interface gives us the Mouse Drag information. We add it the same way as MouseListener. See if you can pick out the steps.

Note that we only change colors on a click, on a drag we just note a new location and keep redrawing points.




import java.awt.*;
import javax.swing.*;
import java.awt.event.*;


public class SpotsArt extends JFrame
        implements MouseListener, MouseMotionListener{
    Point clickPoint=new Point(-1,-1);
    int radius = 7;
    Color color;
    boolean first=true;

    public SpotsArt(String name)
    {
        super(name);
        this.setSize(800, 400);
        setVisible(true);

    // Our JFrame is a Component.  We want to register it to
    // fire MouseEvents according to the MouseListener interface
    // The class which will handle this interface in the JFrame itself.
    // This implies our JFrame must implement the MouseListener interface.

       addMouseListener(this);
    // MouseMotionListener interface gives us the Drag capability

       addMouseMotionListener(this);
    }

    public void paint(Graphics g)
    {
       // find out how big our drawing area is
       if (first)
       {
           first = false;
           super.paint(g);
       }
       int w = getSize().width;
       int h = getSize().height;

       g.drawRect(0,0,w -1, h -1); // draw boundary

       if (clickPoint.x >= 0)
       {
          g.setColor(color);
          g.fillOval(clickPoint.x - radius,    clickPoint.y - radius,
                    2*radius, 2*radius);
       }
    }
    public void mousePressed(MouseEvent e)
    {
       clickPoint.x = e.getX();
       clickPoint.y = e.getY();

       color = new Color(
           (float)Math.random(), (float)Math.random(), (float)Math.random());
       // Note that nothing happens unless I tell java to repaint my screen
       repaint();
    }

    public void mouseClicked(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}

    public void mouseDragged(MouseEvent e)
    {
        clickPoint.x = e.getX();
        clickPoint.y = e.getY();
        // Note that nothing happens unless I tell java to repaint my screen
        repaint();
    }
    public void mouseMoved(MouseEvent e){} // part of MouseMotionListener

    public static void main(String[] args) {
        SpotsArt spots = new SpotsArt("My Spots Art Program");
    } // end of main


}





Last Updated: October 10, 2009 9:29 PM