User events: mouse click, mouse down, mouse up, mouse drag, mouse within a component (focus), key pressed, particular key pressed, etc.
Solution 1: have controls listen to all events, check whether they should respond, and then respond. Roughly this was the JDK 1.0 model.
Solution 2: Tell controls what events they can respond to and have them direct messages to appropriate actions (methods within object) . This is the "delegation" model of JDK 1.1 and is more efficient.
Model:
user action --> source object (control) ----> target object (listener)
What we need to do is:
So what do we need to do?
This makes c respond to the event by sending a message to the object.
Foo c = new Foo(); Button b = new Button("clear"); b.addActionListener(c); //.. buttons generate action events ... // ActionListener has only 1 method, actionPerformed .. class Foo implements ActionListener { ... public void actionPerformed() { whatever foo should do when button is pressed } ... }
import java.applet.*; import java.awt.*; import java.awt.event.*; // Design 1: Everyone talks to applet and gets messages from applet. // Applet acts as god class. This is usually the simpliest design. class MyCanvas extends Canvas { Color linecolor= Color.black; public void paint(Graphics g) { Dimension d = getSize(); g.drawRect(2,2,d.width-4,d.height-4); } public void clear() { Graphics g = getGraphics(); Dimension d = getSize(); Color c = getBackground(); g.setColor(c); g.fillRect(0,0,d.width,d.height); repaint(); //.. repaint() schedules update(). update() (typically) calls paint(). } public void changeColor() { Color[] colors ={Color.red,Color.black,Color.blue,Color.magenta}; linecolor = colors[random(colors.length)]; } public int random(int i) { return (int) Math.floor(Math.random()*i); } public void drawLine(Point p, Point q) { Graphics g = getGraphics(); g.setColor(linecolor); g.drawLine(p.x,p.y,q.x,q.y); g.drawOval(q.x,q.y,2,2); } public void drawOval(Point p) { Graphics g = getGraphics(); g.drawOval(p.x,p.y,2,2); } } public class MouseTest extends Applet implements ActionListener, MouseListener { Panel top; Button clear; Button change; MyCanvas mycanvas; Point begin,end; public void init() { top = new Panel(); clear = new Button("Clear"); clear.addActionListener(this); change = new Button("Change Color"); change.addActionListener(this); top.add(new Label("Mouse click to draw lines")); top.add(clear); top.add(change); setLayout(new BorderLayout()); add(top,"North"); mycanvas = new MyCanvas(); mycanvas.addMouseListener(this); add(mycanvas,"Center"); } public void actionPerformed(ActionEvent actevt) { Object arg = actevt.getSource(); if (arg == clear ) mycanvas.clear(); else if (arg == change) mycanvas.changeColor(); } public void mousePressed(MouseEvent me) { begin = me.getPoint(); mycanvas.drawOval(begin); } public void mouseReleased(MouseEvent me ) { end = me.getPoint(); mycanvas.drawLine(begin,end); } public void mouseClicked(MouseEvent me) {} public void mouseEntered(MouseEvent me) {} public void mouseExited(MouseEvent me) {} }In the next design we group related activities more finely. The code is longer, but may allow easier changes. Code is simpliest when its structure reflects the organization of the computation.
import java.applet.*; import java.awt.*; import java.awt.event.*; class MyCanvas extends Canvas { Color linecolor= Color.black; public void paint(Graphics g) // why doesn't this work? { Dimension d = getSize(); g.drawRect(2,2,d.width-4,d.height-4); } public void clear() { Graphics g = getGraphics(); Dimension d = getSize(); Color c = getBackground(); g.setColor(c); g.fillRect(0,0,d.width,d.height); repaint(); } public void changeColor() { Color[] colors ={Color.red,Color.black,Color.blue,Color.magenta}; linecolor = colors[random(colors.length)]; } public int random(int i) { return (int) Math.floor(Math.random()*i); } public void drawLine(Point p, Point q) { Graphics g = getGraphics(); g.setColor(linecolor); g.drawLine(p.x,p.y,q.x,q.y); g.drawOval(q.x,q.y,2,2); } public void drawOval(Point p) { Graphics g = getGraphics(); g.drawOval(p.x,p.y,2,2); } } class ClearButton extends Button { ClearButton(MouseTest mt) { super("Clear"); addActionListener(mt); } } class ChangeButton extends Button { ChangeButton(MouseTest mt) { super("Change Color"); addActionListener(mt); } } public class MouseTest extends Applet implements ActionListener, MouseListener { Panel top; ClearButton clear; ChangeButton change; MyCanvas mycanvas; Point begin,end; public void init() { top = new Panel(); clear = new ClearButton(this); change = new ChangeButton(this); top.add(new Label("Mouse click to draw lines")); top.add(clear); top.add(change); setLayout(new BorderLayout()); add(top,"North"); mycanvas = new MyCanvas(); mycanvas.addMouseListener(this); add(mycanvas,"Center"); } public void actionPerformed(ActionEvent actevt) { Object arg = actevt.getSource(); if (arg == clear ) mycanvas.clear(); else if (arg == change) mycanvas.changeColor(); } public void mousePressed(MouseEvent me) { begin = me.getPoint(); mycanvas.drawOval(begin); } public void mouseReleased(MouseEvent me ) { end = me.getPoint(); mycanvas.drawLine(begin,end); } public void mouseClicked(MouseEvent me) {} public void mouseEntered(MouseEvent me) {} public void mouseExited(MouseEvent me) {} }In this design we examine the interactions between the events.
import java.applet.*; import java.awt.*; import java.awt.event.*; /* Design 2: here we analyze the objects and see where message are going The Listener for the message must be able to see the object generating the message. Message Diagram: clearbutton --> canvas changebutton --> canvas canvas -->(mouse clicks) -->canvas So the buttons will still need to be mediated by the applet, while the canvas can talk to itself. */ class MyCanvas extends Canvas implements MouseListener { Color linecolor= Color.black; //ugh Point begin,end; public void paint(Graphics g) { Dimension d = getSize(); g.drawRect(2,2,d.width-4,d.height-4); } public void clear() { Graphics g = getGraphics(); Dimension d = getSize(); Color c = getBackground(); g.setColor(c); g.fillRect(0,0,d.width,d.height); repaint(); } public void changeColor() { Color[] colors = {Color.red,Color.black,Color.blue,Color.magenta,Color.green}; linecolor = colors[random(colors.length)]; } public int random(int i) { return (int) Math.floor(Math.random()*i); } public void drawLine(Point p, Point q) { Graphics g = getGraphics(); g.setColor(linecolor); g.drawLine(p.x,p.y,q.x,q.y); g.drawOval(q.x,q.y,2,2); } public void drawOval(Point p) { Graphics g = getGraphics(); g.drawOval(p.x,p.y,2,2); } public void mousePressed(MouseEvent me) { begin = me.getPoint(); drawOval(begin); } public void mouseReleased(MouseEvent me ) { end = me.getPoint(); drawLine(begin,end); } public void mouseClicked(MouseEvent me) {} public void mouseEntered(MouseEvent me) {} public void mouseExited(MouseEvent me) {} } public class MouseTest extends Applet implements ActionListener { Panel top; Button clear; Button change; MyCanvas mycanvas; public void init() { mycanvas = new MyCanvas(); top = new Panel(); clear = new Button("Clear"); clear.addActionListener(this); change = new Button("Change Color"); change.addActionListener(this); top.add(new Label("Mouse click to draw lines")); top.add(clear); top.add(change); setLayout(new BorderLayout()); add(top,"North"); mycanvas.addMouseListener(mycanvas); add(mycanvas,"Center"); } public void actionPerformed(ActionEvent actevt) { Object arg = actevt.getSource(); if (arg == clear) mycanvas.clear(); else if (arg == change) mycanvas.changeColor(); } }
import java.applet.*; import java.awt.*; import java.awt.event.*; // Version using inner classes. Arguable bad style. public class MouseTest extends Applet { Panel top; Button clear; Button change; MyCanvas mycanvas; public void init() { mycanvas = new MyCanvas(); top = new Panel(); clear = new Button("clear"); clear.addActionListener(mycanvas); change = new Button("Change Color"); change.addActionListener(mycanvas); top.add(new Label("Mouse click to draw lines")); top.add(clear); top.add(change); setLayout(new BorderLayout()); add(top,"North"); mycanvas.addMouseListener(mycanvas); add(mycanvas,"Center"); } class MyCanvas extends Canvas implements MouseListener, ActionListener //.. note: inner class { Color linecolor= Color.black; Point begin,end; public void paint(Graphics g) { Dimension d = getSize(); g.drawRect(2,2,d.width-4,d.height-4); } public void clear() { Graphics g = getGraphics(); Dimension d = getSize(); Color c = getBackground(); g.setColor(c); g.fillRect(0,0,d.width,d.height); repaint(); } public void changeColor() { Color[] colors = {Color.red,Color.black,Color.blue,Color.magenta,Color.green}; linecolor = colors[random(colors.length)]; } public int random(int i) { return (int) Math.floor(Math.random()*i); } public void drawLine(Point p, Point q) { Graphics g = getGraphics(); g.setColor(linecolor); g.drawLine(p.x,p.y,q.x,q.y); g.drawOval(q.x,q.y,2,2); } public void drawOval(Point p) { Graphics g = getGraphics(); g.drawOval(p.x,p.y,2,2); } public void mousePressed(MouseEvent me) { begin = me.getPoint(); drawOval(begin); } public void mouseReleased(MouseEvent me ) { end = me.getPoint(); drawLine(begin,end); } public void mouseClicked(MouseEvent me) {} public void mouseEntered(MouseEvent me) {} public void mouseExited(MouseEvent me) {} public void actionPerformed(ActionEvent actevt) { Object arg = actevt.getSource(); if (arg == clear) clear(); else if (arg == change) changeColor(); } } }
Control | Registers Interest | Receives Event |
Button | addActionListener(..) | actionPerformed |
List | ||
MenuItem | ||
TextField | ||
Checkbox | addItemListener | itemStateChanged |
Choice | ||
List | ||
CheckBoxMenuItem | ||
Dialog Frame | addWindowListener | windowClosing |
windowOpening | ||
windowIconified | ||
windowDeiconified | ||
windowClosed | ||
windowActivated | ||
windowDeactivated | ||
Dialog Frame | addComponentListener | componentMoved |
componentHidden | ||
componentResized | ||
componentShown | ||
ScrollBar | addAdjustmentListener | adjustmentValueChanged |
Canvas | addMouseListener | mousePressed |
Dialog | mouseReleased | |
Frame | mouseEntered | |
Panel | mouseExited | |
Window | mouseClicked | |
Canvas | addMouseMotionListener | mouseDragged |
Dialog | mouseMoved | |
Frame | ||
Panel | ||
Window | ||
Component | addKeyListener | keyPressed |
keyReleased | ||
keyTyped | ||
Component | addFocusListener | focusGained |
focusLost | ||
TextComponent | addTextListener | textValueChanged |