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

User Inputs

In this set of notes we are going to look at User inputs (i.e. Mouse clicks and key strokes). To receive User Inputs, you have to work with Interfaces. 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 JFrame 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.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;


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)
    {
       super.paint(g);
       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());

Replace the statement:
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 an ArrayList.

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




import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.JFrame;


//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<Data> arr = new ArrayList<Data>();

    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)
    {
       super.paint(g);
       Dimension d = getSize();
       Insets insets = getInsets();
       int left=insets.left;
       int right = insets.right;
       int top = insets.top;
       int bottom = insets.bottom;

       g.setColor(Color.yellow);
       g.fillRect(0,0, d.width, d.height);

       g.setColor(Color.red);
       g.drawRect(left, top,d.width -1 -left -right , d.height -1 -top -bottom); // draw boundary

       // Paint all spots
       for (int i=0; i < arr.size(); i++)
       {
           Data data = arr.get(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
       arr.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");
        spots.setVisible(true);
    } // end of main


}





Minimize the screen and then bring it back.

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 ArrayList 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.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;


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);
        spots.setVisible(true);
        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)
    {
       Dimension d = getSize();
       Insets insets = getInsets();
       int left=insets.left;
       int right = insets.right;
       int top = insets.top;
       int bottom = insets.bottom;

       if (first)
       {
           super.paint(g);
           g.setColor(Color.white);
           g.fillRect(0,0, d.width, d.height);
           first = false;
       }

       g.setColor(Color.red);
       g.drawRect(left, top,d.width -1 -left -right , d.height -1 -top -bottom); // 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


}





KeyListener Interface


import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;

public class Key_Text extends JFrame
        implements KeyListener{

    String text2Display="Hi";

    public Key_Text(String name)
    {
        super(name);
        setVisible(true);
        setSize(800, 400);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

       addKeyListener(this);
    }

    public void paint(Graphics g)
    {
       super.paint(g);
       Dimension d = getSize();
       // find out how big our drawing area is
       int frameWidth = d.width;
       int frameHeight = d.height;


       // Font Font names to try: Serif, SansSerif, Courier
       // Font types to try Font.BOLD, Font.ITALIC
       Font myFont;
       FontMetrics fm;
       int height;
       int width;
       int nextSize = 72;
       boolean continueFlag;

       do
       {
          continueFlag=false;

           myFont = new Font("TimesRoman", Font.PLAIN, nextSize);

           fm = getFontMetrics(myFont);

           height = fm.getHeight();
           width = fm.stringWidth(text2Display);
           if (width >= frameWidth)
           {
               nextSize -= 2;
               continueFlag=true;
           }
       }while (continueFlag);

       System.out.println("Frame("+frameWidth+") width("+width+")");

       // Num pixels for font above "line"
       int maxAscent = fm.getMaxAscent();
       // Num pixels for font below "line"
       int maxDescent = fm.getMaxDescent();
       // Num pixels between lowest point of one line and highest point of next line
       int leading = fm.getLeading();
       System.out.println("FontSize="+ nextSize+" Height="+height+" maxAscent="+maxAscent+
               " maxDescent="+maxDescent+ " leading="+leading);

       // Attempt to center text horizontally
       int xStart = frameWidth/2 - width/2;
       int yStart = frameHeight/2 - height/2;
       g.setColor(Color.yellow);
       g.fillRect(xStart, yStart, width, height);

       g.setColor(Color.black);
       g.setFont(myFont);
       g.drawString(text2Display, xStart, yStart+maxAscent);
       g.drawLine(xStart, yStart+maxAscent, xStart+width, yStart+maxAscent);


       System.out.println("Paint:"+text2Display+ "-fontsize="+nextSize + " x,y="+xStart+","+yStart);
    }

    public void keyTyped(KeyEvent e)
    {
        char c = e.getKeyChar();
        System.out.println("Char type="+c);
        int len = text2Display.length();
        switch (c)
        {
        case KeyEvent.VK_BACK_SPACE:
            if (len > 0)
                text2Display = text2Display.substring(0,len-1);
        break;

        case KeyEvent.VK_ENTER:
            text2Display="Enter";
            break;

        case KeyEvent.VK_ESCAPE:
            text2Display="";
            break;

        default:
            text2Display += c;
            break;
        }
        repaint();

    }
    public void keyPressed(KeyEvent e)
    {

    }
    public void keyReleased(KeyEvent e)
    {

    }


    public static void main(String[] args) {
        Key_Text keyTextFrame = new Key_Text("My Key and Text Program");
    } // end of main


}







Other Interfaces that we will encounter with GUI

Listeners.html

Exercises:

1. Take the Spots program and create an internal class to handle the interface methods for MouseListener. This is a different approach.


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;


public class Spots extends JFrame
{

    Point clickPoint=new Point(-1,-1);
    int radius = 7;

    // Inner Class *************************************
    class MyMouseHandler implements MouseListener
    {
        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) {}
    }
    //**************** End of Inner Class

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

        MyMouseHandler mmh = new MyMouseHandler();
        addMouseListener(mmh);
    }

    public void paint(Graphics g)
    {
        super.paint(g);
        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 static void main(String[] args) {
        Spots spots = new Spots("My Spots Program");
        spots.setVisible(true);
    } // end of main


}



2. Take the Spots program and create an internal class derived from the Adapter class associated with the MouseListener interface ---- yet another approach


  // Inner Class *************************************
  // Just swap out the previous MyMouseHandler for the following one:

    class MyMouseHandler extends MouseAdapter
    {
        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();
        }
    }
    //**************** End of Inner Class


3. Note that MouseAdapter probably looks something like:


  class MouseAdapter implements MouseListener
    {
        public void mousePressed(MouseEvent e){}
        public void mouseClicked(MouseEvent e) {}
        public void mouseEntered(MouseEvent e) {}
        public void mouseExited(MouseEvent e) {}
        public void mouseReleased(MouseEvent e) {}
    }


4. Demonstrate anonymous classes using Spots


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;


public class Spots extends JFrame
{

    Point clickPoint=new Point(-1,-1);
    int radius = 7;



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

        addMouseListener(new MouseAdapter()
        {
            public void mousePressed(MouseEvent e)
            {
                clickPoint.x = e.getX();
                clickPoint.y = e.getY();
                repaint();
            }
        }

        );
    }

    public void paint(Graphics g)
    {
        super.paint(g);
        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 static void main(String[] args) {
        Spots spots = new Spots("My Spots Program");
        spots.setVisible(true);
    } // end of main


}



Last Updated: September 7, 2013 11:39 PM