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 java.awt.event.*;
import java.applet.*;

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

    public void init()
    {
    // Our Applet 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 Applet itself.
    // This implies our applet must implement the MouseListener interface.

       addMouseListener(this);
    }

    public void paint(Graphics g)
    {
       // 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 applet = new Spots();
        Frame aFrame = new Frame("Spots");

        aFrame.add(applet);
        aFrame.setSize(380,200);
        // Normally the following call comes from the Browser
        applet.init();

        aFrame.setVisible(true);
    } // end of main


}


Click to make points

Spots2.java

This example is almost the same as Spots except for:

1. For fun, I decided to create random colors for the spots --- Red spots are just too boring.
2. The most significant change however, is overriding the update method of the Component class. Note that we keep drawing new spots.
3. I lied a little bit above. It turns out that repaint is actually a request to the system to call the update method. The normal update method in the Component class clears the whole screen and then calls paint.
4. By overriding update, we avoided clearing the screen --- we just had update call paint only.
5. Create a bunch of spots and then cover your window with any other window (like a PAD window). Then uncover your spots and you will see that Spots2.java should only remember one spot(last one) out of your collection.


import java.awt.*;
import java.awt.event.*;
import java.applet.*;

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

public void init()
    {
       addMouseListener(this);
    }


public void paint(Graphics g)
{
    int w = getSize().width;
    int h = getSize().height;

    // For fun, let's use a random color for each new spot
    Color color = new Color(
        (float)Math.random(), (float)Math.random(), (float)Math.random());

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

    if (clickPoint.x >= 0)
    {
        g.setColor(color);
        g.fillOval(clickPoint.x - radius,    clickPoint.y - radius,
                    2*radius, 2*radius);
    }
}

// We will override the normal update routine which would clear the
// screen on each repaint operation before calling paint.

    public void update(Graphics g)
    {
       paint(g);
    }

    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) {
        Spots2 applet = new Spots2();
        Frame aFrame = new Frame("Spots2");

        aFrame.add(applet);
        aFrame.setSize(380,200);
        // Normally the following call comes from the Browser
        applet.init();

        aFrame.setVisible(true);
    } // end of main
}



Click to make points

Cover artwork and then uncover artwork

Spots2save.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 could try to store out information in an ArrayList, however, most browsers don't understand ArrayList because browsers often have pretty old JREs. Netscape 6 would be happy, but any I.E. or Netscape 4.x would have problems.

So this is where it is nice to know about the Vector class which is an older version of the ArrayList. We also need to restrict ourselves to methods that were available on JDK 1.1.8. That's why I keep the link to the online help for JDK 1.1.8.

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 Vector class.

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

The should work in all browsers if this window is the active one page in the browser. In otherwords, you are covering the applet with some other window and then uncover the applet.

In Netscape 4.xxx, you get one additional feature. You can actually go to another web page and then come back to the applet and see the spots redrawn. This feature doesn't work if your browser reconstructs the applet when you come back to the page (I.E. and Netscape 6).


import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.util.*;

// Class to save Spot Data
class Data
{
    Point p;
    Color c;

    Data(Point p1, Color c1)
    {
        p=p1;
        c=c1;
    }
}

public class Spots2save extends Applet
    implements MouseListener{
  int radius = 7;

  // Storage to save our Spot Data
 // ArrayList arrsave=new ArrayList(); // Not supported in I.E.
  Vector    arrsave= new Vector();

  public void init()
    {
       addMouseListener(this);
    }

  public void paint(Graphics g)
  {
    int w = getSize().width;
    int h = getSize().height;
    Data d;

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

    // Paint all spots
    for (int i=0; i < arrsave.size(); i++)
    {
        //d = (Data)arrsave.get(i);  // Not supported in I.E.
        d = (Data)arrsave.elementAt(i);
        g.setColor(d.c);
        g.fillOval(d.p.x - radius,    d.p.y - radius,
                    2*radius, 2*radius);
    }
  }

  public void mousePressed(MouseEvent e)
    {
       int x = e.getX();
       int y = e.getY();
       Point p = new Point(x,y);

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

       // Add a new Spot to the Data collection
       //arrsave.add(d); // Not supported in I.E.
       arrsave.addElement(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) {
        Spots2save applet = new Spots2save();
        Frame aFrame = new Frame("Spots2save");

        aFrame.add(applet);
        aFrame.setSize(380,200);
        // Normally the following call comes from the Browser
        applet.init();

        aFrame.setVisible(true);
    } // end of main


}




Click to make points

Cover artwork and then uncover artwork

Spots3.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 java.awt.event.*;
import java.applet.*;

public class Spots3 extends Applet
implements MouseListener, MouseMotionListener{
Point clickPoint=new Point(-1,-1);
int radius = 7;
Color color;

public void init()
{
    // MouseMotionListener interface gives us the Drag capability

    addMouseListener(this);
    addMouseMotionListener(this);
}
public void paint(Graphics g)
{
    int w = getSize().width;
    int h = getSize().height;


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

    if (clickPoint.x >= 0)
    {
        g.setColor(color);
        g.fillOval(clickPoint.x - radius,    clickPoint.y - radius,
                    2*radius, 2*radius);
    }
}

// We will override the normal update routine which would clear the
// screen on each repaint operation before calling paint.

public void update(Graphics g)
{
    paint(g);
}

// ---------------------------
// Routines needed for the MouseListener Interface
// ---------------------------
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());
    System.out.println("Color = " + color);

    // 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){}
// ---------------------------
// Routines needed for the MouseMotionListener Interface
// ---------------------------
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) {
        Spots3 applet = new Spots3();
        Frame aFrame = new Frame("Spots3");

        aFrame.add(applet);
        aFrame.setSize(380,200);
        // Normally the following call comes from the Browser
        applet.init();

        aFrame.setVisible(true);
    } // end of main


}



Click and Drag

SpotsCanvas.java

Suppose we want to combine one of our Spots programs with some of our Components (i.e. Button, Choice, etc.). We create a Choice box to allow us to change from drawing Ovals to Rectangles. Also we can choose filled versus open figures. Adobe was a little worried about competition from my promising Graphics tool.

We can create a drawing area that acts some what like a Component and can be added to a container just like a Button. In our previous drawing examples, the drawing area took over the whole container.

The best way to do this is to derive a class from the Canvas class. In order for this to work, you have to override the paint method (no surprise here). You also need to call setSize to give your Canvas a size (the default is a size of 0,0).

Once you have done this, you can do any desired drawing in the Canvas area, and you can add your Canvas based class to your container as easily as a Button class.


import java.awt.*;
import java.awt.event.*;
import java.applet.*;

// Create out own component derived from Canvas

class MyCanvas extends Canvas implements MouseListener
{
    Point clickPoint=new Point(-1,-1);
    int radius = 20;
    String drawType = "fillOval";
    String[] drawTypes={"fillOval", "drawOval","fillRect", "drawRect"};

    MyCanvas(int width, int height)
    {
       setSize(width, height);
       addMouseListener(this);
    }
    void setDrawType(String type)
    {
        drawType = type;
    }

    // Must override paint if we want anything out of this

    public void paint(Graphics g)
    {
       int w = getSize().width;
       int h = getSize().height;
       Color color = new Color(1.0f, 0.0f, 0.0f);

       g.drawRect(1,0,w -2, h -1);

       if (clickPoint.x >= 0)
       {
          g.setColor(color);
          if (drawType.equals("fillOval"))
              g.fillOval(clickPoint.x - radius,    clickPoint.y - radius,
                    2*radius, 2*radius);
          else if (drawType.equals("drawOval"))
              g.drawOval(clickPoint.x - radius,    clickPoint.y - radius,
                    2*radius, 2*radius);
          else if (drawType.equals("fillRect"))
              g.fillRect(clickPoint.x - radius,    clickPoint.y - radius,
                    2*radius, 2*radius);
          else if (drawType.equals("drawRect"))
              g.drawRect(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 class SpotsCanvas extends Applet
        implements ActionListener{
    int width = 380;
    int height = 280;
    MyCanvas myCanvas = new MyCanvas(width, height -80);
    Choice drawType = new Choice();


    public void init()
    {
        Button update = new Button("update");
        add(myCanvas);
        add(update);
        update.addActionListener(this);
        add(drawType);
        for (int i=0; i < myCanvas.drawTypes.length; i++)
            drawType.add(myCanvas.drawTypes[i]);

    }
    public void actionPerformed(ActionEvent evt) {
         myCanvas.setDrawType( drawType.getSelectedItem()  );
    }

    public static void main(String[] args) {
        Frame aFrame = new Frame("SpotsCanvas");
        SpotsCanvas applet = new SpotsCanvas();

        aFrame.add(applet);
        aFrame.setSize(applet.width, applet.height);
        // Normally the following call comes from the Browser
        applet.init();

        aFrame.setVisible(true);
    } // end of main


}



Select the desired option and click the update button

Last Updated: December 13, 2002 9:22 AM