Now you'll see how to invoke a method whose name has been typed into a TextField. This is an artificial example of reflection. In fact few programs really require reflection, but application builder tools rely heavily on reflection and introspection (which is built on top of reflection to support Beans).
You're now going to add two methods which will be invoked by using reflection. Given a string naming a method, a Method object will be retrieved and subsequently invoked with the proper arguments. In order to support the reflection classes, add the following package import statement at the end of the current list of imports:
import java.lang.reflect.*;
Now have a look at the methods that will be called based on TextField input events or Choice ItemSelected events:
First add a paint method that draws a rectangle of variable size:
public void paint(Graphics g) {
g.drawRect(x,y,w,h);
}
Instance variables should be declared
at the top of the class definition
to control the rectangle's size:
public class ChoiceApplet04 extends Applet
{
...
int x,y,w,h;
...
}
The paint method will be called
automatically to update the applets
frame with the newly drawn rectangle
whenever a repaint method is called.
This is done inside two new methods
that you must now define:
public void big() {
System.out.println("big()");
x=10; y=50; w=100; h=100;
repaint();
}
public void small() {
System.out.println("small()");
x=10; y=50; w=20; h=20;
repaint();
}
The first draws a big rectangle the second draws a small one. You will not be calling these methods directly, but indirectly throught the Reflect lookup mechansism. This is the essence of last four sections of exercises. The method which does the lookup and invocation is called invoke:
public void invoke(String mName) {
try {
Method m = ChoiceApplet04.class.getDeclaredMethod(mName, null);
m.invoke(this, null);
}
catch (Exception ex) {
System.err.println("no such method: "+mName);
}
}
Given a String, mName
which names the method,
the Class object for
ChoiceApplet04 can call
getDeclaredMethod
to get a Method object, m.
To get the applet's class, use:
ChoiceApplet04.class.
The
getDeclaredMethod
gets two arguments: a String,
naming the method for the
class, and an array of argments.
Essentially you are
the signature of
the desired method in the
call
ChoiceApplet04.class.getDeclaredMethod(mName, null);Since no arguments are required by either the
big or small methods,
null is given as the second argument.
Now that you have the desired Method
object in the variable m,
you can invoke it as follows:
m.invoke(this, null);
If either the method lookup or the invocation
fails, an exception is thrown in the
try block. If this
happens, the exception handling code
in the catch block reports that
"no such method:" exists and prints
the offending method name.
Method names "big" or "small" will
work; any other names will throw
an exception.
Just for tidiness, you'll want to
keep the text displayed in
the TextField consistent with
the selection in the Choice
component and vice versa. Add
the following code to the
actionPerformed method of
the inner class handling
events for theTextField:
if (mName.equals("big") || mName.equals("small"))
theChoice.select(mName);
else
theChoice.select("unknown");
Immediatley after this code, add a
statment to call invoke based
on the String now in the TextField:
invoke(mName);
The same call must be added to the
event handler code for the Choice
component.
The respective listener registration
and event handler definitions look
like this:
theChoice.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
System.out.println("ENTER----->theChoice ActionListener");
String mName = (String) e.getItem();
System.out.println("mName: " + mName);
String pString = e.paramString(); // useful for Debugging
System.out.println("pString: " + pString);
theTextField.setText(mName);
invoke(mName);
System.out.println("EXIT------>theChoice ActionListener");
}
});
theTextField.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("ENTER----->theTextField ActionListener");
String mName = e.getActionCommand();
System.out.println("mName: " + mName);
if (mName.equals("big") || mName.equals("small"))
theChoice.select(mName);
else
theChoice.select("unknown");
invoke(mName);
System.out.println("EXIT------>theTextField ActionListener");
}
});
}
Hopefully that wasn't too bad. Once you get the hang of inner classes, events and event listeners, you'll be on solid ground for programming JDK 1.1 applications and applets. Reflection is worth knowing about in certain situations. As mentioned if your are building programming environments and tools that need to find out the capabilities of classes at run time, you'll find Reflection is indespensible. For typical programs, however, you should focus on the new event model.
You'll find more detailed examples of event handlers, inner classes, reflection, and introspection in the next four sections starting with LINKFILE $NEXTFILE LINKTEXT Automatically Resized Beans ).
You can use TestChoiceApplet04.html to test the applet.
A makefile for this lesson automates source code compilation, JAR file construction, and copying of JAR files to the appropriate BeanBox directory. You'll have to edit several of the variables in the makefile to indicate the location of your JDK 1.1 and BDK installation directories.
You may want to look at the final source file for ChoiceApplet04.java to verify changes.
|
|
|||
|
|
|
Questions? 30-Jan-98 Copyright © 1996,1997 Sun Microsystems Inc. All Rights Reserved. |
|