Greetings...

Java Take-Off Step Four:

Listening to your users.


Here's a first program:

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

// appends come common MouseEvents to a TextArea
public class MouseTest extends Applet implements MouseListener
{
    // the TextArea to receive MouseEvents
    private TextArea textArea;
    
    // this method overrides the init method from the Applet class  
    public void init()
    {
	setLayout(new GridLayout(2, 1));
	
	// set up a new Panel object that will fire mouse events to the applet
	Panel p = new Panel();
	p.setBackground(new Color(0, 127, 255));
	p.add(new Label("I LOVE Mouse Events!"));
	p.addMouseListener(this);
	add(p);
	
	// now add the TextArea to the applet
	textArea = new TextArea();
	add(textArea);
    }
    
    // appends the sent String, the component fired upon, and the point where 
    // it happened to the TextArea 
    private void reportMouseEvent(String s, MouseEvent e)
    {
	String point = "(" + e.getX() + ", " + e.getY() + ")";
	textArea.append(s + e.getSource().getClass() + " at " + point + "\n");
    }
    
    // methods implemented in the MouseListener interface; their usage should
    // be self-explanatory     
    
    public void mouseClicked(MouseEvent e) 
    {
	// for this method, differentiate between left and right clicks
	if(e.getModifiers() == MouseEvent.BUTTON1_MASK)
	    {
		reportMouseEvent("Mouse left-clicked on ", e);
	    }
	
	if(e.getModifiers() == MouseEvent.BUTTON3_MASK)
	    {
		reportMouseEvent("Mouse right-clicked on ", e);
	    }
    }
    
    public void mouseEntered(MouseEvent e) 
    {
	reportMouseEvent("Mouse entered ", e);
    }
    
    public void mouseExited(MouseEvent e) 
    {
	reportMouseEvent("Mouse exited ", e);
    }
    
    public void mousePressed(MouseEvent e) 
    {
	reportMouseEvent("Mouse pressed over ", e);
    }
    
    public void mouseReleased(MouseEvent e) 
    {
	reportMouseEvent("Mouse released over ", e);
    }
    
} // MouseTest
EXERCISES This second program is a bit more involved:
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

// the ColorDescription class stores a Color as well as its String 
// description. this class is provided purely as a convenience for 
// associating a Color with a String 
class ColorDescription
{
    // associates a Color with a text String, declared public for convenience 
    public Color color;
    public String text;
    
    public ColorDescription(Color c, String s)
    {
	color = c;
	text  = s;
    }
    
    public boolean matches(String s)
    {
	return text.equals(s);
    }
} // ColorDescription 

// the Scribble applet allows the user to draw points and lines with 
// the mouse, as well as choose the current pen color. 

public class Scribble extends Applet implements ItemListener, 
						ActionListener,
						MouseListener, 
						MouseMotionListener
{
    private Choice colorChooser;  // a combo-box to store colors 
    private Color  currentColor;  // the current pen color 
    
    // an array of Colors with their associated String names
    // all you need to do is edit this list to add or remove choices 
    // from the applet 
    private final ColorDescription[] colors = new ColorDescription[] {
	new ColorDescription(Color.black,  "Black"),
	new ColorDescription(Color.red,    "Red"),
	new ColorDescription(Color.green,  "Green"), 
	new ColorDescription(Color.blue,   "Blue"),
	new ColorDescription(Color.yellow, "Yellow"),
	new ColorDescription(Color.orange, "Orange"), 
	new ColorDescription(Color.gray,   "Gray"), 
	new ColorDescription(Color.cyan,   "Cyan")
	    };
    
    // the source and destination points for drawing lines 
    private Point p1;
    private Point p2;          
    
    // this method overrides the init method from the Applet class 
    public void init()
    {
	p1 = null;
	p2 = null;
	
	setBackground(Color.white);
	
	// remember to register ourself to receive mouse events 
	addMouseListener(this);
	addMouseMotionListener(this);
	
	// set the cursor to something snazzy 
	setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
	
	currentColor = colors[0].color;
	
	// create a "sidebar" containing applet commands 
	createSidebar();
    }
    
    // this method overrides the init method from the Applet class 
    public void destroy()
    {
	// release any listeners added during the applet's lifecycle 
	removeMouseListener(this);
	removeMouseMotionListener(this);
	
	colorChooser.removeItemListener(this);
    }
    
    // creates a Frame containing the drop-down box of Color choices
    // and a button to clear the applet window 
    private void createSidebar()
    {
	// for each ColorDescription in the colors array, extract the text 
	// component and add it to the choice listing 
	colorChooser = new Choice();
	for(int i = 0; i < colors.length; i++)
	    {
		colorChooser.add(colors[i].text);
	    }
	colorChooser.addItemListener(this);
	
	// create a "clear window" button 
	Button b = new Button("Clear Window");
	b.addActionListener(this);
	
	// create the frame 
	Frame f = new Frame();
	f.setLocation(getX() + getSize().width + 8, getY());
	f.setLayout(new GridLayout(3, 1, 5, 5));
	f.setBackground(Color.yellow);
	f.add(new Label("Pen Color:", Label.CENTER));
	f.add(colorChooser);
	f.add(b);
	f.pack();
	f.show();
    }
    
    // draws points connecting points p1 and p2 using the current pen color 
    private void drawPoints()
    {
	Graphics g = getGraphics();
	g.setColor(currentColor);
	g.drawLine(p1.x, p1.y, p2.x, p2.y);
    }
    
    // called when the sidebar's "clear window" button is pressed 
    public void actionPerformed(ActionEvent e)
    {
	repaint();
    }
    
    // called when the drop-box is changed 
    public void itemStateChanged(ItemEvent e)
    {
	String color = colorChooser.getSelectedItem();
	
	// match the current pen color with the selected item 
	for(int i = 0; i < colors.length; i++)
	    {
		if(colors[i].matches(color))
                    {
			// set the color 
			currentColor = colors[i].color;
			break;
                    }
	    }               
    }               
    
    /** methods implemented in the MouseMotionListener interface */ 
    
    public void mouseMoved(MouseEvent e) 
    { 
	// do nothing... 
    }
    
    public void mouseDragged(MouseEvent e) 
    {
	// set the points if they are not yet set 
	if(p1 == null)
	    {
		p1 = new Point(e.getX(), e.getY());
	    }
	if(p2 == null)
	    {
		p2 = new Point(e.getX(), e.getY());
	    }
	
	// update the points and draw the point 
	p1.x = p2.x;
	p1.y = p2.y;
	
	p2.x = e.getX();
	p2.y = e.getY();
	
	drawPoints();
    }
    
    /** methods implemented in the MouseListener interface */ 
    
    public void mouseClicked(MouseEvent e) 
    {
	// do nothing... 
    }
    
    public void mouseEntered(MouseEvent e) 
    {
	// do nothing... 
    }
    
    public void mouseExited(MouseEvent e) 
    {
	// do nothing... 
    }
    
    // allows a point to be drawn when the mouse button is down but
    // the mouse is not necessarily being "dragged" 
    public void mousePressed(MouseEvent e) 
    {
	mouseDragged(e);
    }
    
    // release the points to allow non-continuous drawing 
    public void mouseReleased(MouseEvent e) 
    {
	p1 = null;
	p2 = null;
    }
    
} // Scribble
EXERCISES Here's the last program, a very simple (but basic) test.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

// this applet allows the user to move a black rectangle 
// using the arrow keys. the user can also change the applet's 
// background color with the 'R', 'G', 'B', and 'W' keys.  It also 
// shows the different ways a KeyEvent object can be interpreted. 
public class KeyTest extends Applet implements KeyListener
{
    // moveable black rectangle 
    private Rectangle r;
    
    // current background color for the applet 
    private Color backColor;
    
    // this method overrides the init method from the Applet class 
    public void init()
    {
	r = new Rectangle(0, 0, 20, 10);
	
	backColor = Color.white;
	
	addKeyListener(this);
    }
    
    // paints the rectangle at the updated position
    public void paint(Graphics g)
    {
	setBackground(backColor);
	g.fillRect(r.x, r.y, r.width, r.height);
    }
    
    /** methods implemented in the KeyListener interface */
    
    public void keyPressed(KeyEvent e) 
    {
	// for this method, use the key code to generate movement
	int keyCode = e.getKeyCode();
	
	// move the rectangle
	if(keyCode == KeyEvent.VK_LEFT)
	    {
		r.x -= 5;
		if(r.x < 0) r.x = 0;
		repaint();
	    }
	else if(keyCode == KeyEvent.VK_RIGHT)
	    {
		r.x += 5;
		if(r.x > getSize().width-r.width) 
		    r.x = getSize().width-r.width;
		repaint();
	    }
	else if(keyCode == KeyEvent.VK_UP)
	    {
		r.y -= 5;
		if(r.y < 0) r.y = 0;
		repaint();
	    }
	else if(keyCode == KeyEvent.VK_DOWN)
	    {
		r.y += 5;
		if(r.y > getSize().height-r.height) 
		    r.y = getSize().height-r.height;
		repaint();
	    }              
    }
    
    public void keyReleased(KeyEvent e) 
    {
	// do nothing...
    }
    
    public void keyTyped(KeyEvent e)  
    {
	// for this method, use the actual key char to call action 
	char keyChar = e.getKeyChar();
	
	// change the background color
	switch(keyChar)
	    {
	    case 'r':
		{    
		    backColor = Color.red;
		    repaint();
		    break;
		} 
	    case 'g':
		{    
		    backColor = Color.green;
		    repaint();
		    break;
		} 
	    case 'b':
		{    
		    backColor = Color.blue;
		    repaint();
		    break;
		} 
	    case 'w':
		{
		    backColor = Color.white; 
		    repaint();
		    break;
		}
	    }
    }
    
} // KeyTest
EXERCISES


Last updated: Apr 6, 2002 by Adrian German for A201/A597/I210/A348/A548/T540/NC009