FileDocCategorySizeDatePackage
CommandProxy.javaAPI DocExample3164Sat Jan 24 10:44:30 GMT 2004je3.reflect

CommandProxy.java

/*
 * Copyright (c) 2004 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 3nd Edition.
 * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
 * You may study, use, and modify it for any non-commercial purpose,
 * including teaching and use in open-source projects.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book, 
 * please visit http://www.davidflanagan.com/javaexamples3.
 */
package je3.reflect;
import java.lang.reflect.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;

/**
 * This class is an InvocationHandler based on a Map of method names to Command
 * objects.  When the invoke() method is called, the name of the method to be
 * invoked is looked up in the map, and the associated Command, if any is
 * invoked.  Arguments passed to invoke() are always ignored.  Note that there
 * is no public constructor for this class.  Instead, there is a static factory
 * method for creating Proxy objects that use an instance of this class.
 * Pass the interface to be implemented and a Map of name/Command pairs.
 **/
public class CommandProxy implements InvocationHandler {
    Map methodMap;  // Maps method names to Command objects that implement 

    // private constructor
    private CommandProxy(Map methodMap) { this.methodMap = methodMap; }

    // This method implements InvocationHandler, and invokes the Command,
    // if any associated with the name of Method m.  It ignores args[] and
    // always returns null.
    public Object invoke(Object p, Method m, Object[] args) throws Throwable {
	String methodName = m.getName();
	Command command = (Command) methodMap.get(methodName);
	if (command != null) command.invoke();
	return null;
    }

    // Return an object that implements the specified interface, using the
    // name-to-Command map as the implementation of the interface methods.
    public static Object create(Class iface, Map methodMap) {
	InvocationHandler handler = new CommandProxy(methodMap);
	ClassLoader loader = handler.getClass().getClassLoader();
	return Proxy.newProxyInstance(loader, new Class[] { iface }, handler);
    }

    // This is a test class to demonstrate the use of CommandProxy.
    static class Test {
	public static void main(String[] args)  throws java.io.IOException {
	    // Set up a simple GUI
	    javax.swing.JFrame f = new javax.swing.JFrame("Command Test");
	    javax.swing.JButton b = new javax.swing.JButton("Hello World");
	    f.getContentPane().add(b, java.awt.BorderLayout.CENTER);
	    f.pack();
	    f.show();

	    // Set up the Map of method names to Command objects
	    Map methodMap = new HashMap();
	    methodMap.put("focusGained",Command.parse(b,"setText(\"hello\")"));
	    methodMap.put("focusLost",Command.parse(b,"setText(\"goodbye\")"));

	    // Use CommandProxy.create() to create a proxy FocusListener
	    FocusListener l =
		(FocusListener)CommandProxy.create(FocusListener.class,
						   methodMap);
		       
	    // Use the synthetic FocusListener
	    b.addFocusListener(l);
	}
    }
}