Download Events and Reflection.

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Bean Communication
COMP434B Software Design
• Events are the primary mechanism by which Java
components interact with each other
• One Bean generates an event and one or more other
Beans receive it
JavaBeans: Events and Reflection
• Java 1.0 event model was based on the
component containment hierarchy
• If a component didn’t handle a particular event then it
propagated up to the containing component
• Simple - OK for writing basic applets
• Doesn’t scale well to complicated interfaces
2
Bean Communication
• Java 1.1 delegation event model…
• Provides a standard mechanism for a source to
generate an event and send it to a set of listeners
• Event
• An object that describes some state change in a source
• Can be generated when a user interacts with an element
in a GUI
 Eg pressing a button, moving a slider, dragging the mouse etc
• Events may also be generated that are not directly caused
by user input
Bean Communication
• Java 1.1 delegation event model…
• A source - generate events
• Sources have three main responsibilities:
• Provide methods that allow listeners to register and
deregister for notifications about a specific type of event
• Generate events
• Send events to all registered listeners
 Multiple listeners - multicasting
 Single listener - unicasting
 Eg arrival of incoming data, expiration of a software timer,
overflow of a buffer
3
Bean Communication
• Java 1.1 delegation event model…
• Registering and deregistering methods:
public void addTypeListener( TypeListener el)
public void addTypeListener( TypeListener el) throws
TooManyListenersException
Public void removeTypeListener(TypeListener el)
• Type is the type of the event, and el is the event listener
• Eg. javax.swing.AbstractButton
• Provides common behaviours for buttons and menu items
(subclasses: JButton, JMenuItem, JToggleButton)
• Generates an action event when pressed/selected
4
Bean Communication
• Java 1.1 delegation event model…
• A listener - receives event notifications
• Listeners have three main responsibilities
• Register to receive notifications about specific events
 Call appropriate registration method of the source
• Implement an interface to receive events of that type
• Deregister if it no longer wants to receive notifications
about a specific type of event
 Call appropriate deregistration method of the source
• public void addActionListener(ActionListener al)
• public void removeActionListener(ActionListener al)
5
6
1
Bean Communication
Bean Communication
• Event classes…
• A set of classes is provided to represent the various types of
UI events (AWT events)
Object
• Eg. ActionListener interface provides one
method to receive action events
void actionPerformed(ActionEvent ae)
• ae is the ActionEvent object generated by the source
• When a button is pressed, the actionPerformed
method of all registered listeners is invoked and the
event is passed as an argument to that method
EventObject
AWTEvent
ActionEvent
ContainerEvent
ComponentEvent
FocusEvent
InputEvent
KeyEvent
7
Bean Communication
• Event classes…
AdjustmentEvent
ItemEvent
PaintEvent
TextEvent
WindowEvent
8MouseEvent
Bean Communication
• Event classes…
• EventObject class extends Object
• AWTEvent class extends EventObject
• Is part of the java.util package
• Is the superclass of all event state objects
• Constructor : EventObject(Object source)
• Is part of the java.awt package
• All AWT event types are subclasses of AWTEvent
• One of its constructors: AWTEvent(Object source, int
 Source is the object that generates the event
id)
 Source is the object generating the event, id identifies the type of
event
• Has two methods :
• Two frequently used methods:
Object getSource() - return the generating object
String toString() - return a String equivalent of the event
 int getId()
 String toString()
9
10
Bean Communication
AWT Events Examples
• Action and Item Events
• Listener interfaces
• EventListener interface is part of the java.util
package
• It does not define any constants or methods, but
exists only to identify those interfaces that process
events
• All event listener interfaces must extend this interface
• Events typically have a corresponding listener
interface
• BlahEvent - BlahListener
11
• Usually generated when buttons are pressed and menu items
are selected respectively
package actionevents;
import java.awt.*;
import javax.swing.JButton;
public class ActionSource1 extends JButton {
public ActionSource1() {
super("ActionSource1");
}
}
2
package actionevents;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JTextArea;
import javax.swing.JPanel;
package actionevents;
import java.awt.*;
import javax.swing.JComboBox;
public class ActionReceiver extends JPanel
implements ActionListener, ItemListener {
private JTextArea ta;
public class ActionSource2 extends JComboBox {
public ActionSource2() {
addItem("Item 1");
addItem("Item 2");
addItem("Item 3");
}
public ActionReceiver() {
ta = new JTextArea(10,20);
add(ta);
}
}
. . .
public void actionPerformed(ActionEvent ae) {
String ac = ae.getActionCommand();
int modifiers = ae.getModifiers();
String s = ac;
if((modifiers & ActionEvent.ALT_MASK) != 0) {
s += ", ALT_MASK";
}
if((modifiers & ActionEvent.CTRL_MASK) != 0) {
s += ", CTRL_MASK";
}
if((modifiers & ActionEvent.META_MASK) != 0) {
s += ", META_MASK";
}
if((modifiers & ActionEvent.SHIFT_MASK) != 0) {
s += ", SHIFT_MASK";
}
ta.append(s + "\n");
}
public void itemStateChanged(ItemEvent e) {
String item = (String)e.getItem();
String info =
(e.getStateChange() == ItemEvent.SELECTED)
? " (selected)"
: " (deselected)";
ta.append(item+info+"\n");
}
}
. . .
public class ActionEventsDemo {
public static void main(String [] args) {
. . .
ActionSource1 as1 = new ActionSource1();
ActionSource2 as2 = new ActionSource2();
ActionReceiver ar = new ActionReceiver();
. . .
if (mode == 1) {
as1.setBounds(10,10,150,30);
jf.getContentPane().add(as1);
as1.addActionListener(ar);
} else {
as2.setBounds(10,10,150,30);
jf.getContentPane().add(as2);
as2.addActionListener(ar);
as2.addItemListener(ar);
}
. . .
AWT Events Examples
• Mouse Events
• Are generated when the mouse is clicked, dragged, moved,
pressed or released (also when mouse pointer enters or exits a
component)
• MouseEvent class defines many int constants
• MOUSE_CLICKED, MOUSE_DRAGGED, MOUSE_ENTERED,
MOUSE_EXITED etc
• Some commonly used methods of MouseEvent:
• Point getPoint() - returns a Point object encapsulating the
position of the mouse
• getX(), getY() - return the x and y coordinates of the mouse
• Two listener interfaces - MouseListener and
MouseMotionListener
18
3
package mouseevents;
import java.awt.*;
import javax.swing.JPanel;
public class MouseSource extends JPanel {
public MouseSource() {
Dimension d = new Dimension(100,100);
setMinimumSize(d);
setPreferredSize(d);
setMaximumSize(d);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension d = getSize();
g.drawRect(0, 0, d.width – 1, d.height – 1);
}
}
public void mouseEntered(MouseEvent me) {
ta.append("mouse entered\n");
}
public void mouseExited(MouseEvent me) {
ta.append("mouse exited\n");
}
public void mousePressed(MouseEvent me) {
ta.append("mouse pressed\n");
}
public void mouseReleased(MouseEvent me) {
ta.append("mouse released\n");
}
public void mouseDragged(MouseEvent me) {
ta.append("mouse dragged\n");
}
public void mouseMoved(MouseEvent me) {
ta.append("mouse moved\n");
}
package mouseevents;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
public class MouseReceiver extends JPanel
implements MouseListener, MouseMotionListener {
private JTextArea ta;
public MouseReceiver() {
ta = new JTextArea(15, 40);
JScrollPane js = new JScrollPane(ta);
add(js);
}
public void mouseClicked(MouseEvent me) {
ta.append("mouse clicked\n");
}
. . .
Adapter Classes
• An adapter class provides empty implementations
of all methods defined in a specific event listener
interface
• Useful if you only want to process a subset of the
events that are received by a particular interface
• MouseListener has five methods. If for example you
only wanted to process mouseClicked() then your
class could extend MouseAdapter and overide only
the mouseClicked method
• Can’t be used in this way if your class already extends
some other class
}
22
Anonymous Inner Classes
• An inner class is one that is defined within the
scope of another class
• Has access to all the variables and methods of the
enclosing class
• An anonymous inner class is one that does not
have a name
• Use when you only ever need one object of the class
• Can be extremely useful when writing code to
process events
23
package dot;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;
public class Dot extends JPanel {
private Point p;
public Dot() {
Dimension d = new Dimension(200, 200);
setMinimumSize(d);
setPreferredSize(d);
setMaximumSize(d);
p = new Point(100, 100);
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
changePoint(me.getPoint());
}
});
}
. . .
4
public void changePoint(Point newP) {
p = newP;
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension d = getSize();
g.drawRect(0, 0, d.width – 1, d.height – 1);
g.fillRect(p.x – 2, p.y – 2, 4, 4);
}
Dynamic Event Handlers
• java.beans.EventHandler (introduced in Java 1.3)
• Provides support for dynamically generating event
listeners
• Can handle simple situation where event listener
methods execute a single statement involving an
incoming event and a target object
• Only provides a subset of what can be done with inner
classes
}
• However, memory and disk footprint is smaller than for
inner classes
• Using EventHandler requires one class per listener type,
using anonymous inner classes requires one class per
26
listener object
java.beans.EventHandler
• Has various static factory methods for creating
proxy objects that implement a given listener
interface
package dotV2;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JPanel;
import java.beans.EventHandler;
public class Dot extends JPanel {
private Point p;
public Dot() {
Dimension d = new Dimension(200, 200);
. . .
Object handler =
EventHandler.create(MouseListener.class, this,
"changePoint", "point", "mouseClicked");
• EventHandler objects are used behind the scenes to
encapsulate info about the event, the target object,
the method to call on the target and any argument to
the method
• java.lang.reflect.Proxy class implements listener
methods; calls to listener methods are encoded and
passed on to the EventHandler’s invoke method
addMouseListener((MouseListener)handler);
}
. . .
27
java.beans.EventHandler
• Intended to be used by builder tools—we will
see how later
• Removes the need for Beans to implement
specific listener interfaces
• Allows builder tools to connect arbitrary beans
together
• Weaker typing—specific listener interfaces
implemented by a bean can be bypassed
• Limited to transferring a single property from
source event or bean to target bean
29
package actioneventsV2;
. . .
public class ActionSource2 extends JComboBox {
public String getCurrentSelectedItemText() {
return getSelectedItem().toString();
}
public ActionSource2() {
addItem("Item 1"); addItem("Item 2"); addItem("Item 3");
}
}
public class ActionReceiver extends JPanel {
private JTextArea ta;
public ActionReceiver() {
ta = new JTextArea(10,20);
add(ta);
}
public void acceptText(String text) {
ta.append(text + "\n");
}
5
package mouseeventsV2;
. . .
public class MouseReceiver extends JPanel {
private JTextArea ta;
public MouseReceiver() {
ta = new JTextArea(15, 40);
JScrollPane js = new JScrollPane(ta);
add(js);
}
Custom Events
• Custom events are useful when one of your objects
wants to notify another object about a change in its state
• Six steps involved:
• You must define a new class to describe the event (must extend
EventObject)
• You must define a new interface for listeners to receive this
type of event (must extend EventListener)
• The source must provide methods to allow listeners to register
and deregister for event notifications
• The source must provide code to generate the event and send it
to all registered listeners
• The listener must implement the interface to receive the event
• The listener must register/deregister to receive the notifications
public void mouseClicked() {
ta.append("mouse clicked\n");
}
public void mouseEntered() {
ta.append("mouse entered\n");
}
public void mouseExited() {
ta.append("mouse exited\n");
}
. . .
Colour Event Example
32
package cselector;
import java.util.*;
public interface ColorListener extends EventListener {
package cselector;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class ColorEvent extends EventObject {
private Color color;
public ColorEvent(Object source, Color color) {
super(source);
this.color = color;
}
public Color getColor() {
return color;
}
public void changeColor(ColorEvent ce);
}
package cselector;
import java.awt.*;
import javax.swing.JPanel;
public class Painter extends JPanel implements ColorListener
{
private Color color;
// constructor + paintComponent method omitted – see source
. . .
public void setColor(Color c) {
color = c; repaint();
}
public void changeColor(ColorEvent ce) {
color = ce.getColor(); repaint();
}
}
}
package cselector;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
import java.util.*;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JLabel;
. . .
public Color getColor() {
return color;
}
public void fireColorEvent(ColorEvent ce) {
Vector v;
synchronized(this) {
v = (Vector)listeners.clone();
}
for(int i = 0; i < v.size(); i++) {
ColorListener cl = (ColorListener)v.elementAt(i);
cl.changeColor(ce);
}
}
public class Selector extends JPanel
implements AdjustmentListener {
private Color color;
private Vector listeners;
private JScrollBar rScrollbar, gScrollbar, bScrollbar;
// constructor, paintComponent & scrollbar handling code
// omitted – see source for details
}
public void addColorListener(ColorListener cl) {
listeners.addElement(cl);
}
public void removeColorListener(ColorListener cl) {
listeners.removeElement(cl);
} . . .
6
Reflection and Introspection
• Reflection is the ability to obtain information
about the fields, constructors and methods of a
class at runtime
• The typical Bean developer does not write code that
uses reflection directly
• However, it is useful to have some understanding of
reflection because Introspection is based on it
Reflection
• Class
• The Java Virtual Machine creates an instance of the
class java.lang.Class for each type, including
classes, interfaces, arrays, and simple types
• Class provides various instance methods that allow
you to get information about that type
• Provides more than 30 different instance methods! See the
javadocs
37
38
package reflect;
public class IsInterfaceDemo {
public static void main(String args[]) {
try {
// Get the class object
Class c = Class.forName(args[0]);
// Determine if it represents a class or interface
if(c.isInterface()) {
System.out.println(args[0] + " is an interface");
}
else {
System.out.println(args[0] + " is not an interface");
}
}
catch(Exception ex) {
// the printStackTrace method is extremely useful for
// debugging :-)
ex.printStackTrace();
}
Reflection
• The java.lang.reflect package contains
interfaces and classes that encapsulate
information about constructors, methods,
fields etc.
• Eg. java.lang.reflect.Field contains methods
that allow you to read and write the value
of a field within another object (subject to
Java language access control)
}
}
40
package reflect;
import java.lang.reflect.*;
public class GetFieldsDemo {
public static void main(String args[]) {
try {
// Get the class object
Class c = Class.forName(args[0]);
// Display the fields
Field fields[] = c.getFields();
for(int i = 0; i < fields.length; i++) {
System.out.println(fields[i].getName());
}
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
Reflection
• The class Method in java.lang.reflect alows you
to get information about a method
• Some methods in Method:
Class [] getExceptionTypes()
Class [] getParameterTypes()
Class getReturnType()
Object invoke(Object obj, Object [] args)
 Allows a builder tool to dynamically invoke a method of a Bean!
This is exactly what is needed to customize a Bean by accessing
its properties and to connect several Beans
42
7
// Generate parameters array
Object parameters[] = new Double[nparameters];
for(int i = 0; i < nparameters; i++) {
parameters[i] = new Double(args[i + 2]);
}
package reflect;
import java.lang.reflect.*;
// invoke a method in a class, where the class name,
// method name, and any args are supplied on the
// command line
public class InvokeDemo {
// Invoke method
Object r;
if(Modifier.isStatic(m.getModifiers())) {
r = m.invoke(null, parameters);
}
else {
r = m.invoke(c.newInstance(), parameters);
}
// Display results
if (r != null) {
System.out.println(r);
}
public static void main(String args[]) {
try {
// Get the class object
Class c = Class.forName(args[0]);
// Get reference to Method object
int nparameters = args.length – 2;
Class parameterTypes[] = new Class[nparameters];
for(int i = 0; i < nparameters; i++) {
parameterTypes[i] = double.class;
}
Method m = c.getMethod(args[1], parameterTypes);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
8