Java/Reflection/JavaBean
Содержание
Get Color
<source lang="java">
/* Java Reflection in Action Ira R. Forman and Nate Forman ISBN 1932394184 Publisher: Manning Publications Co.
- /
import java.awt.Color; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class GetColor {
static public void main(String[] args) { Rabbit rabbit = new Rabbit(); //start extract snippet3 setObjectColor(rabbit, Color.WHITE); //stop extract snippet3 if (!rabbit.setColorCalled) throw new RuntimeException(); } //start extract setObjectColor public static void setObjectColor(Object obj, Color color) { Class cls = obj.getClass(); //#1 try { Method method = cls.getMethod("setColor", //#2 new Class[] { Color.class }); method.invoke(obj, new Object[] { color }); //#3 } catch (NoSuchMethodException ex) { //#4 throw new IllegalArgumentException(cls.getName() + " does not support" + "method setColor(:Color)"); } catch (IllegalAccessException ex) { //#5 throw new IllegalArgumentException( "Insufficient access permissions to call" + "setColor(:Color) in class " + cls.getName()); } catch (InvocationTargetException ex) { //#6 throw new RuntimeException(ex); } } //stop extract setObjectColor static public class Rabbit { public boolean setColorCalled = false; public void setColor(Color c) { setColorCalled = true; } }
}
</source>
Returns attribute"s getter method. If the method not found then NoSuchMethodException will be thrown.
<source lang="java">
import java.lang.reflect.Method; import java.util.HashSet; import java.util.List; import java.util.Set; /*
* JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */
public class Main {
/** * Returns attribute"s getter method. If the method not found then * NoSuchMethodException will be thrown. * * @param cls * the class the attribute belongs too * @param attr * the attribute"s name * @return attribute"s getter method * @throws NoSuchMethodException * if the getter was not found */ public final static Method getAttributeGetter(Class cls, String attr) throws NoSuchMethodException { StringBuffer buf = new StringBuffer(attr.length() + 3); buf.append("get"); if (Character.isLowerCase(attr.charAt(0))) { buf.append(Character.toUpperCase(attr.charAt(0))).append(attr.substring(1)); } else { buf.append(attr); } try { return cls.getMethod(buf.toString(), (Class[]) null); } catch (NoSuchMethodException e) { buf.replace(0, 3, "is"); return cls.getMethod(buf.toString(), (Class[]) null); } }
}
</source>
Returns attribute"s setter method. If the method not found then NoSuchMethodException will be thrown.
<source lang="java">
import java.lang.reflect.Method; import java.util.HashSet; import java.util.List; import java.util.Set; /*
* JBoss, Home of Professional Open Source * Copyright 2005, JBoss Inc., and individual contributors as indicated * by the @authors tag. See the copyright.txt in the distribution for a * full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */
public class Main {
/** * Returns attribute"s setter method. If the method not found then * NoSuchMethodException will be thrown. * * @param cls * the class the attribute belongs to * @param attr * the attribute"s name * @param type * the attribute"s type * @return attribute"s setter method * @throws NoSuchMethodException * if the setter was not found */ public final static Method getAttributeSetter(Class cls, String attr, Class type) throws NoSuchMethodException { StringBuffer buf = new StringBuffer(attr.length() + 3); buf.append("set"); if (Character.isLowerCase(attr.charAt(0))) { buf.append(Character.toUpperCase(attr.charAt(0))).append(attr.substring(1)); } else { buf.append(attr); } return cls.getMethod(buf.toString(), new Class[] { type }); }
}
</source>
Uses reflection and JavaBeans introspection to
<source lang="java">
/*
* Copyright (c) 2000 David Flanagan. All rights reserved. * This code is from the book Java Examples in a Nutshell, 2nd 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. * You may distribute it non-commercially as long as you retain this notice. * For a commercial use license, or to purchase the book (recommended), * visit http://www.davidflanagan.ru/javaexamples2. */
import java.awt.Color; import java.awt.ruponent; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.Vector; import javax.swing.ButtonGroup; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JRadioButtonMenuItem; import javax.swing.JTabbedPane; import javax.swing.SwingUtilities; import javax.swing.UIManager; /**
* This class is a program that uses reflection and JavaBeans introspection to * create a set of named components, set named properties on those components, * and display them. It allows the user to view the components using any * installed look-and-feel. It is intended as a simple way to experiment with * AWT and Swing components, and to view a number of the other examples * developed in this chapter. It also demonstrates frames, menus, and the * JTabbedPane component. */
public class ShowComponent {
// The main program public static void main(String[] args) { // Process the command line to get the components to display Vector components = getComponentsFromArgs(args); // Create a frame (a window) to display them in JFrame frame = new JFrame("ShowComponent"); // Handle window close requests by exiting the VM frame.addWindowListener(new WindowAdapter() { // Anonymous inner class public void windowClosing(WindowEvent e) { System.exit(0); } }); // Set up a menu system that allows the user to select the // look-and-feel of the component from a list of installed PLAFs JMenuBar menubar = new JMenuBar(); // Create a menubar frame.setJMenuBar(menubar); // Tell the frame to display it JMenu plafmenu = createPlafMenu(frame); // Create a menu menubar.add(plafmenu); // Add the menu to the menubar // Create a JTabbedPane to display each of the components JTabbedPane pane = new JTabbedPane(); // Now add each component as a tab of the tabbed pane // Use the unqualified component classname as the tab text for (int i = 0; i < components.size(); i++) { Component c = (Component) components.elementAt(i); String classname = c.getClass().getName(); String tabname = classname .substring(classname.lastIndexOf(".") + 1); pane.addTab(tabname, c); } // Add the tabbed pane to the frame. Note the call to getContentPane() // This is required for JFrame, but not for most Swing components frame.getContentPane().add(pane); // Set the frame size and pop it up frame.pack(); // Make frame as big as its kids need frame.setVisible(true); // Make the frame visible on the screen // The main() method exits now but the Java VM keeps running because // all AWT programs automatically start an event-handling thread. } /** * This static method queries the system to find out what Pluggable * Look-and-Feel (PLAF) implementations are available. Then it creates a * JMenu component that lists each of the implementations by name and allows * the user to select one of them using JRadioButtonMenuItem components. * When the user selects one, the selected menu item traverses the component * hierarchy and tells all components to use the new PLAF. */ public static JMenu createPlafMenu(final JFrame frame) { // Create the menu JMenu plafmenu = new JMenu("Look and Feel"); // Create an object used for radio button mutual exclusion ButtonGroup radiogroup = new ButtonGroup(); // Look up the available look and feels UIManager.LookAndFeelInfo[] plafs = UIManager .getInstalledLookAndFeels(); // Loop through the plafs, and add a menu item for each one for (int i = 0; i < plafs.length; i++) { String plafName = plafs[i].getName(); final String plafClassName = plafs[i].getClassName(); // Create the menu item JMenuItem item = plafmenu.add(new JRadioButtonMenuItem(plafName)); // Tell the menu item what to do when it is selected item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { // Set the new look and feel UIManager.setLookAndFeel(plafClassName); // Tell each component to change its look-and-feel SwingUtilities.updateComponentTreeUI(frame); // Tell the frame to resize itself to the its // children"s new desired sizes frame.pack(); } catch (Exception ex) { System.err.println(ex); } } }); // Only allow one menu item to be selected at once radiogroup.add(item); } return plafmenu; } /** * This method loops through the command line arguments looking for class * names of components to create and property settings for those components * in the form name=value. This method demonstrates reflection and JavaBeans * introspection as they can be applied to dynamically created GUIs */ public static Vector getComponentsFromArgs(String[] args) { Vector components = new Vector(); // List of components to return Component component = null; // The current component PropertyDescriptor[] properties = null; // Properties of the component Object[] methodArgs = new Object[1]; // We"ll use this below nextarg: // This is a labeled loop for (int i = 0; i < args.length; i++) { // Loop through all arguments // If the argument does not contain an equal sign, then it is // a component class name. Otherwise it is a property setting int equalsPos = args[i].indexOf("="); if (equalsPos == -1) { // Its the name of a component try { // Load the named component class Class componentClass = Class.forName(args[i]); // Instantiate it to create the component instance component = (Component) componentClass.newInstance(); // Use JavaBeans to introspect the component // And get the list of properties it supports BeanInfo componentBeanInfo = Introspector .getBeanInfo(componentClass); properties = componentBeanInfo.getPropertyDescriptors(); } catch (Exception e) { // If any step failed, print an error and exit System.out.println("Can"t load, instantiate, " + "or introspect: " + args[i]); System.exit(1); } // If we succeeded, store the component in the vector components.addElement(component); } else { // The arg is a name=value property specification String name = args[i].substring(0, equalsPos); // property name String value = args[i].substring(equalsPos + 1); // property // value // If we don"t have a component to set this property on, skip! if (component == null) continue nextarg; // Now look through the properties descriptors for this // component to find one with the same name. for (int p = 0; p < properties.length; p++) { if (properties[p].getName().equals(name)) { // Okay, we found a property of the right name. // Now get its type, and the setter method Class type = properties[p].getPropertyType(); Method setter = properties[p].getWriteMethod(); // Check if property is read-only! if (setter == null) { System.err.println("Property " + name + " is read-only"); continue nextarg; // continue with next argument } // Try to convert the property value to the right type // We support a small set of common property types here // Store the converted value in an Object[] so it can // be easily passed when we invoke the property setter try { if (type == String.class) { // no conversion needed methodArgs[0] = value; } else if (type == int.class) { // String to int methodArgs[0] = Integer.valueOf(value); } else if (type == boolean.class) { // to boolean methodArgs[0] = Boolean.valueOf(value); } else if (type == Color.class) { // to Color methodArgs[0] = Color.decode(value); } else if (type == Font.class) { // String to Font methodArgs[0] = Font.decode(value); } else { // If we can"t convert, ignore the property System.err.println("Property " + name + " is of unsupported type " + type.getName()); continue nextarg; } } catch (Exception e) { // If conversion failed, continue with the next arg System.err.println("Can"t convert "" + value + "" to type " + type.getName() + " for property " + name); continue nextarg; } // Finally, use reflection to invoke the property // setter method of the component we created, and pass // in the converted property value. try { setter.invoke(component, methodArgs); } catch (Exception e) { System.err.println("Can"t set property: " + name); } // Now go on to next command-line arg continue nextarg; } } // If we get here, we didn"t find the named property System.err.println("Warning: No such property: " + name); } } return components; }
}
</source>