Title: Mouse Interfaces : Spots Painting
Course: CPS 161: An Intro to Programming with Java - DL MM MASTER

Mouse Interfaces: Spots Painting

- As you continue in Java, you will find that Java uses interfaces quite a bit.
- An Interface can sometimes look like a class, but it isn't a class. An interface is a special file which defines a list of methods. If a class claims to implement the interface, it is obligated to have all of the methods in the interface.
- First I want to review a couple of places where I introduced Interfaces previously
- I'm going to work through an example where Java uses Interfaces for Mouse Userinterface inputs.
- 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 -

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 JFrame. 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 from JFrame. We do this with the call
addMouseListener(this);
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);
        setSize(800, 400);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
		
    // 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)
    {
       Dimension d = getSize();
       g.setColor(Color.white);
       g.fillRect(0,0, d.width, d.height);
       // Make a red spot
       Color color = new Color(1.0f, 0.0f, 0.0f);

       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");
        spots.setVisible(true);
    } // 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 replacing the regular code for clearing the screen with

if (first)
{
first=false;
// Code for clearing screen
}

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.*;


//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;
    Data[] arrSave = new Data[10000];
    int count=0;

    public SpotsSave(String name)
    {
        super(name);
        setSize(800, 400);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

    // 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)
    {
       Dimension d = getSize();
       g.setColor(Color.white);
       g.fillRect(0,0, d.width, d.height);
       g.setColor(Color.black);

       g.drawRect(0,0,d.width -1, d.height -1); // draw boundary

       // Paint all spots
       for (int i=0; i < count; i++)
       {
           Data data = arrSave[i];
           g.setColor(data.c);
           g.fillOval(data.x - radius,    data.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
       if (count < arrSave.length)
            arrSave[count++] = 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");
        spots.setVisible(true);
    } // end of main


}





Rework the above to use the ArrayList<Data> instead of an array. Key things:

ArrayList is a class that provides a growable array class. We will only use the fundamental parts of this feature. It is covered in more detail in Advanced Java.

//Constructing:
ArrayList<Data> arrSave = new ArrayList<Data>();

// adding an object
Data d = new Data(x, y, color);
arrSave.add(d);

//fetching an item at index i:
Data d = arrSave.get(i);

SpotsArt.java

I want to add another interface to our program.

We want to be able to drag our mouse and get a brush effect. Note that we have removed the ArrayList 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);
        setSize(800, 400);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

    // 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
       Dimension d = getSize();
       if (first)
       {
           first = false;

           g.setColor(Color.white);
           g.fillRect(0,0, d.width, d.height);
           g.setColor(Color.black);
       }


       g.drawRect(0,0,d.width -1, d.height -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");
        spots.setVisible(true);
    } // end of main


}







Last Updated: November 13, 2013 11:19 AM