The 11th chapter introduces the new "reflection" concept of Java 1.1, and uses this concept to query a specific class of methods-either a complete list of all methods or a subset of the list (the name matches the keyword we specify). The great benefit of that example is that it automatically displays all the methods, does not force us to traverse through the inheritance structure, and examines the underlying classes at each level. So, it's actually an effective tool for saving US programming time: Because most Java methods have names that are very comprehensive and detailed, they can effectively identify the names of the methods that contain a particular keyword. If you find a name that meets the criteria, you can consult the online Help documentation directly from it.
But the 11th example also has a flaw, it does not use AWT, it is only a pure command line application. Here, we're going to make an improved GUI version that automatically refreshes the output as we type the characters, and allows us to cut and paste in the output:
: Displaymethods.java//Display The methods of any class inside//a window.
Dynamically narrows your search.
Import java.awt.*;
Import java.awt.event.*;
Import java.applet.*;
Import java.lang.reflect.*;
Import java.io.*;
public class Displaymethods extends Applet {class cl;
Method[] m;
Constructor[] ctor;
string[] n = new string[0];
TextField name = new TextField, searchfor = new TextField (30);
CheckBox strip = new CheckBox ("Strip Qualifiers");
TextArea results = new TextArea (40, 65);
public void init () {strip.setstate (true);
Name.addtextlistener (New Namel ());
Searchfor.addtextlistener (New Searchforl ());
Strip.additemlistener (New Stripl ());
Panel top = new Panel (), lower = new Panel (), p = new Panel ();
Top.add (New Label ("Qualified class Name:");
Top.add (name);
Lower.add (New Label ("String to search for:");
Lower.add (searchfor);
Lower.add (strip); P.setlayout (New BorderLayout ());
P.add (top, Borderlayout.north);
P.add (lower, borderlayout.south);
SetLayout (New BorderLayout ());
Add (P, Borderlayout.north);
Add (results, borderlayout.center); Class Namel implements TextListener {public void textvaluechanged (TextEvent e) {String nm = Name.gettext ()
. Trim ();
if (nm.length () = = 0) {results.settext ("No match");
n = new String[0];
Return
try {cl = Class.forName (NM);
catch (ClassNotFoundException ex) {Results.settext ("No match");
Return
} m = Cl.getmethods ();
ctor = Cl.getconstructors ();
Convert to an array of strings:n = new String[m.length + ctor.length];
for (int i = 0; i < m.length i++) n[i] = m[i].tostring ();
for (int i = 0; i < ctor.length i++) N[i + m.length] = ctor[i].tostring ();
Redisplay (); } void Redisplay () {//Create the result set:string[] rs = new String[n.length];
String find = Searchfor.gettext ();
int j = 0; Select from the ' list if find exists:for (int i = 0; i < n.length; i++) {if (find = = null) rs[j++]
= N[i];
else if (N[i].indexof (Find)!=-1) rs[j++] = N[i];
} results.settext (""); if (strip.getstate () = = true) for (int i = 0; i < J; i++) Results.append (Stripqualifiers.strip (
Rs[i]) + "\ n");
else//Leave qualifiers on for (int i = 0; i < J; i++) Results.append (rs[i] + "\ n");
Class STRIPL implements ItemListener {public void itemstatechanged (ItemEvent e) {redisplay ();
Class Searchforl implements TextListener {public void textvaluechanged (TextEvent e) {redisplay ();
} public static void Main (string[] args) {displaymethods applet = new Displaymethods ();
Frame aframe = new Frame ("Display Methods");
Aframe.addwindowlistener (New Windowadapter () { public void windowclosing (WindowEvent e) {system.exit (0);
}
});
Aframe.add (applet, borderlayout.center);
Aframe.setsize (500,750);
Applet.init ();
Applet.start ();
Aframe.setvisible (TRUE);
} class Stripqualifiers {private Streamtokenizer st;
Public stripqualifiers (String qualified) {st = new Streamtokenizer (new StringReader (qualified));
St.ordinarychar (");
public string GetNext () {string s = null; try {if (St.nexttoken ()!= streamtokenizer.tt_eof) {switch (st.ttype) {case Streamtok
Enizer.tt_eol:s = null;
Break
Case streamtokenizer.tt_number:s = double.tostring (st.nval);
Break
Case streamtokenizer.tt_word:s = new String (st.sval);
Break
Default://single character in ttype s = string.valueof ((char) st.ttype); Catch in}}}(IOException e)
{System.out.println (e);
return s;
public static string strip (String qualified) {stripqualifiers sq = new stripqualifiers (qualified);
String s = "", si;
while (si = Sq.getnext ())!= null) {int lastdot = Si.lastindexof ('. ');
if (Lastdot!=-1) si = si.substring (lastdot + 1);
s + + si;
return s; }
} ///:~
Some of the things in the program have been seen before. Like many GUI programs in this book, this can be used as a stand-alone application or as a program piece (applet). Moreover, the Stripqualifiers class is exactly the same as its performance in chapter 11th.
The GUI contains a text field (TextField) named name, or the name of the class in which you want to find it, and another text field, named Searchfor, where you can optionally enter a certain text that you want to find in the method list. CheckBox (checkbox) allows us to indicate whether the final wish is to use the full name in the output or to delete the preceding various qualification information. Finally, the results are displayed in a "text area" (TextArea).
You will notice that this program does not use any buttons or other components and cannot start a search with them. This is because both the text field and the check box are monitored by their listener (Listener) objects. As soon as a change is made, the list of results is updated immediately. If you change the text in the Name field, the new text is captured in the Namel class. If the text is not empty, it is used in class.forname () to try to find the class. Of course, the name may become incomplete while the text is being typed, and class.forname () will fail, which means it will "throw" a violation. The violation will be caught and textarea will be set to "NoMatch" (no match). But as long as you type a correct name (including capitalization), Class.forName () succeeds, and GetMethods () and GetConstructors () return an array of method and constructor objects, respectively. Each of these arrays is converted to a string through ToString () (This produces a complete method or builder signature), and two lists are merged into N-a separate array of strings. The array n is a member of the Displaymethods class and is used for the displayed update when the redisplay () is invoked.
If you change the checkbox or Searchfor component, their listener will simply invoke redisplay (). Redisplay () creates a temporary array that contains a string named RS (RS represents the result set--result set). The result set is either copied directly from N (no find keyword), or selectively copied from the string containing the Find keyword in n. Finally, check the strip Checkbox to see if the user wants to remove the extra part of the name (the default is "Yes"). If the answer is yes, do it with Stripqualifiers.strip (), and on the contrary, simply show the list.
In Init (), you might think that you need to do a lot of heavy work when setting up a layout. In fact, the layout of the components is likely to require very little work. But the advantage of using borderlayout like this is that it allows the user to change the size of the window and, in particular, make the textarea (text area) Larger, which means we can change the size so that we see longer names without scrolling.
When programming, you will find it particularly necessary to keep the tool running, because it provides one of the best ways to try to determine what method to call.