同步操作将从 cxylk/Java-Notes 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/** Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************/package java.beans;import java.lang.reflect.InvocationHandler;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Proxy;import java.lang.reflect.Method;import java.security.AccessControlContext;import java.security.AccessController;import java.security.PrivilegedAction;import sun.reflect.misc.MethodUtil;import sun.reflect.misc.ReflectUtil;/*** The <code>EventHandler</code> class provides* support for dynamically generating event listeners whose methods* execute a simple statement involving an incoming event object* and a target object.* <p>* The <code>EventHandler</code> class is intended to be used by interactive tools, such as* application builders, that allow developers to make connections between* beans. Typically connections are made from a user interface bean* (the event <em>source</em>)* to an application logic bean (the <em>target</em>). The most effective* connections of this kind isolate the application logic from the user* interface. For example, the <code>EventHandler</code> for a* connection from a <code>JCheckBox</code> to a method* that accepts a boolean value can deal with extracting the state* of the check box and passing it directly to the method so that* the method is isolated from the user interface layer.* <p>* Inner classes are another, more general way to handle events from* user interfaces. The <code>EventHandler</code> class* handles only a subset of what is possible using inner* classes. However, <code>EventHandler</code> works better* with the long-term persistence scheme than inner classes.* Also, using <code>EventHandler</code> in large applications in* which the same interface is implemented many times can* reduce the disk and memory footprint of the application.* <p>* The reason that listeners created with <code>EventHandler</code>* have such a small* footprint is that the <code>Proxy</code> class, on which* the <code>EventHandler</code> relies, shares implementations* of identical* interfaces. For example, if you use* the <code>EventHandler</code> <code>create</code> methods to make* all the <code>ActionListener</code>s in an application,* all the action listeners will be instances of a single class* (one created by the <code>Proxy</code> class).* In general, listeners based on* the <code>Proxy</code> class require one listener class* to be created per <em>listener type</em> (interface),* whereas the inner class* approach requires one class to be created per <em>listener</em>* (object that implements the interface).** <p>* You don't generally deal directly with <code>EventHandler</code>* instances.* Instead, you use one of the <code>EventHandler</code>* <code>create</code> methods to create* an object that implements a given listener interface.* This listener object uses an <code>EventHandler</code> object* behind the scenes to encapsulate information about the* event, the object to be sent a message when the event occurs,* the message (method) to be sent, and any argument* to the method.* The following section gives examples of how to create listener* objects using the <code>create</code> methods.** <h2>Examples of Using EventHandler</h2>** The simplest use of <code>EventHandler</code> is to install* a listener that calls a method on the target object with no arguments.* In the following example we create an <code>ActionListener</code>* that invokes the <code>toFront</code> method on an instance* of <code>javax.swing.JFrame</code>.** <blockquote>*<pre>*myButton.addActionListener(* (ActionListener)EventHandler.create(ActionListener.class, frame, "toFront"));*</pre>* </blockquote>** When <code>myButton</code> is pressed, the statement* <code>frame.toFront()</code> will be executed. One could get* the same effect, with some additional compile-time type safety,* by defining a new implementation of the <code>ActionListener</code>* interface and adding an instance of it to the button:** <blockquote>*<pre>//Equivalent code using an inner class instead of EventHandler.*myButton.addActionListener(new ActionListener() {* public void actionPerformed(ActionEvent e) {* frame.toFront();* }*});*</pre>* </blockquote>** The next simplest use of <code>EventHandler</code> is* to extract a property value from the first argument* of the method in the listener interface (typically an event object)* and use it to set the value of a property in the target object.* In the following example we create an <code>ActionListener</code> that* sets the <code>nextFocusableComponent</code> property of the target* (myButton) object to the value of the "source" property of the event.** <blockquote>*<pre>*EventHandler.create(ActionListener.class, myButton, "nextFocusableComponent", "source")*</pre>* </blockquote>** This would correspond to the following inner class implementation:** <blockquote>*<pre>//Equivalent code using an inner class instead of EventHandler.*new ActionListener() {* public void actionPerformed(ActionEvent e) {* myButton.setNextFocusableComponent((Component)e.getSource());* }*}*</pre>* </blockquote>** It's also possible to create an <code>EventHandler</code> that* just passes the incoming event object to the target's action.* If the fourth <code>EventHandler.create</code> argument is* an empty string, then the event is just passed along:** <blockquote>*<pre>*EventHandler.create(ActionListener.class, target, "doActionEvent", "")*</pre>* </blockquote>** This would correspond to the following inner class implementation:** <blockquote>*<pre>//Equivalent code using an inner class instead of EventHandler.*new ActionListener() {* public void actionPerformed(ActionEvent e) {* target.doActionEvent(e);* }*}*</pre>* </blockquote>** Probably the most common use of <code>EventHandler</code>* is to extract a property value from the* <em>source</em> of the event object and set this value as* the value of a property of the target object.* In the following example we create an <code>ActionListener</code> that* sets the "label" property of the target* object to the value of the "text" property of the* source (the value of the "source" property) of the event.** <blockquote>*<pre>*EventHandler.create(ActionListener.class, myButton, "label", "source.text")*</pre>* </blockquote>** This would correspond to the following inner class implementation:** <blockquote>*<pre>//Equivalent code using an inner class instead of EventHandler.*new ActionListener {* public void actionPerformed(ActionEvent e) {* myButton.setLabel(((JTextField)e.getSource()).getText());* }*}*</pre>* </blockquote>** The event property may be "qualified" with an arbitrary number* of property prefixes delimited with the "." character. The "qualifying"* names that appear before the "." characters are taken as the names of* properties that should be applied, left-most first, to* the event object.* <p>* For example, the following action listener** <blockquote>*<pre>*EventHandler.create(ActionListener.class, target, "a", "b.c.d")*</pre>* </blockquote>** might be written as the following inner class* (assuming all the properties had canonical getter methods and* returned the appropriate types):** <blockquote>*<pre>//Equivalent code using an inner class instead of EventHandler.*new ActionListener {* public void actionPerformed(ActionEvent e) {* target.setA(e.getB().getC().isD());* }*}*</pre>* </blockquote>* The target property may also be "qualified" with an arbitrary number* of property prefixs delimited with the "." character. For example, the* following action listener:* <pre>* EventHandler.create(ActionListener.class, target, "a.b", "c.d")* </pre>* might be written as the following inner class* (assuming all the properties had canonical getter methods and* returned the appropriate types):* <pre>* //Equivalent code using an inner class instead of EventHandler.* new ActionListener {* public void actionPerformed(ActionEvent e) {* target.getA().setB(e.getC().isD());* }*}*</pre>* <p>* As <code>EventHandler</code> ultimately relies on reflection to invoke* a method we recommend against targeting an overloaded method. For example,* if the target is an instance of the class <code>MyTarget</code> which is* defined as:* <pre>* public class MyTarget {* public void doIt(String);* public void doIt(Object);* }* </pre>* Then the method <code>doIt</code> is overloaded. EventHandler will invoke* the method that is appropriate based on the source. If the source is* null, then either method is appropriate and the one that is invoked is* undefined. For that reason we recommend against targeting overloaded* methods.** @see java.lang.reflect.Proxy* @see java.util.EventObject** @since 1.4** @author Mark Davidson* @author Philip Milne* @author Hans Muller**/public class EventHandler implements InvocationHandler {private Object target;private String action;private final String eventPropertyName;private final String listenerMethodName;private final AccessControlContext acc = AccessController.getContext();/*** Creates a new <code>EventHandler</code> object;* you generally use one of the <code>create</code> methods* instead of invoking this constructor directly. Refer to* {@link java.beans.EventHandler#create(Class, Object, String, String)* the general version of create} for a complete description of* the <code>eventPropertyName</code> and <code>listenerMethodName</code>* parameter.** @param target the object that will perform the action* @param action the name of a (possibly qualified) property or method on* the target* @param eventPropertyName the (possibly qualified) name of a readable property of the incoming event* @param listenerMethodName the name of the method in the listener interface that should trigger the action** @throws NullPointerException if <code>target</code> is null* @throws NullPointerException if <code>action</code> is null** @see EventHandler* @see #create(Class, Object, String, String, String)* @see #getTarget* @see #getAction* @see #getEventPropertyName* @see #getListenerMethodName*/@ConstructorProperties({"target", "action", "eventPropertyName", "listenerMethodName"})public EventHandler(Object target, String action, String eventPropertyName, String listenerMethodName) {this.target = target;this.action = action;if (target == null) {throw new NullPointerException("target must be non-null");}if (action == null) {throw new NullPointerException("action must be non-null");}this.eventPropertyName = eventPropertyName;this.listenerMethodName = listenerMethodName;}/*** Returns the object to which this event handler will send a message.** @return the target of this event handler* @see #EventHandler(Object, String, String, String)*/public Object getTarget() {return target;}/*** Returns the name of the target's writable property* that this event handler will set,* or the name of the method that this event handler* will invoke on the target.** @return the action of this event handler* @see #EventHandler(Object, String, String, String)*/public String getAction() {return action;}/*** Returns the property of the event that should be* used in the action applied to the target.** @return the property of the event** @see #EventHandler(Object, String, String, String)*/public String getEventPropertyName() {return eventPropertyName;}/*** Returns the name of the method that will trigger the action.* A return value of <code>null</code> signifies that all methods in the* listener interface trigger the action.** @return the name of the method that will trigger the action** @see #EventHandler(Object, String, String, String)*/public String getListenerMethodName() {return listenerMethodName;}private Object applyGetters(Object target, String getters) {if (getters == null || getters.equals("")) {return target;}int firstDot = getters.indexOf('.');if (firstDot == -1) {firstDot = getters.length();}String first = getters.substring(0, firstDot);String rest = getters.substring(Math.min(firstDot + 1, getters.length()));try {Method getter = null;if (target != null) {getter = Statement.getMethod(target.getClass(),"get" + NameGenerator.capitalize(first),new Class<?>[]{});if (getter == null) {getter = Statement.getMethod(target.getClass(),"is" + NameGenerator.capitalize(first),new Class<?>[]{});}if (getter == null) {getter = Statement.getMethod(target.getClass(), first, new Class<?>[]{});}}if (getter == null) {throw new RuntimeException("No method called: " + first +" defined on " + target);}Object newTarget = MethodUtil.invoke(getter, target, new Object[]{});return applyGetters(newTarget, rest);}catch (Exception e) {throw new RuntimeException("Failed to call method: " + first +" on " + target, e);}}/*** Extract the appropriate property value from the event and* pass it to the action associated with* this <code>EventHandler</code>.** @param proxy the proxy object* @param method the method in the listener interface* @return the result of applying the action to the target** @see EventHandler*/public Object invoke(final Object proxy, final Method method, final Object[] arguments) {AccessControlContext acc = this.acc;if ((acc == null) && (System.getSecurityManager() != null)) {throw new SecurityException("AccessControlContext is not set");}return AccessController.doPrivileged(new PrivilegedAction<Object>() {public Object run() {return invokeInternal(proxy, method, arguments);}}, acc);}private Object invokeInternal(Object proxy, Method method, Object[] arguments) {String methodName = method.getName();if (method.getDeclaringClass() == Object.class) {// Handle the Object public methods.if (methodName.equals("hashCode")) {return new Integer(System.identityHashCode(proxy));} else if (methodName.equals("equals")) {return (proxy == arguments[0] ? Boolean.TRUE : Boolean.FALSE);} else if (methodName.equals("toString")) {return proxy.getClass().getName() + '@' + Integer.toHexString(proxy.hashCode());}}if (listenerMethodName == null || listenerMethodName.equals(methodName)) {Class[] argTypes = null;Object[] newArgs = null;if (eventPropertyName == null) { // Nullary method.newArgs = new Object[]{};argTypes = new Class<?>[]{};}else {Object input = applyGetters(arguments[0], getEventPropertyName());newArgs = new Object[]{input};argTypes = new Class<?>[]{input == null ? null :input.getClass()};}try {int lastDot = action.lastIndexOf('.');if (lastDot != -1) {target = applyGetters(target, action.substring(0, lastDot));action = action.substring(lastDot + 1);}Method targetMethod = Statement.getMethod(target.getClass(), action, argTypes);if (targetMethod == null) {targetMethod = Statement.getMethod(target.getClass(),"set" + NameGenerator.capitalize(action), argTypes);}if (targetMethod == null) {String argTypeString = (argTypes.length == 0)? " with no arguments": " with argument " + argTypes[0];throw new RuntimeException("No method called " + action + " on " +target.getClass() + argTypeString);}return MethodUtil.invoke(targetMethod, target, newArgs);}catch (IllegalAccessException ex) {throw new RuntimeException(ex);}catch (InvocationTargetException ex) {Throwable th = ex.getTargetException();throw (th instanceof RuntimeException)? (RuntimeException) th: new RuntimeException(th);}}return null;}/*** Creates an implementation of <code>listenerInterface</code> in which* <em>all</em> of the methods in the listener interface apply* the handler's <code>action</code> to the <code>target</code>. This* method is implemented by calling the other, more general,* implementation of the <code>create</code> method with both* the <code>eventPropertyName</code> and the <code>listenerMethodName</code>* taking the value <code>null</code>. Refer to* {@link java.beans.EventHandler#create(Class, Object, String, String)* the general version of create} for a complete description of* the <code>action</code> parameter.* <p>* To create an <code>ActionListener</code> that shows a* <code>JDialog</code> with <code>dialog.show()</code>,* one can write:**<blockquote>*<pre>*EventHandler.create(ActionListener.class, dialog, "show")*</pre>*</blockquote>** @param <T> the type to create* @param listenerInterface the listener interface to create a proxy for* @param target the object that will perform the action* @param action the name of a (possibly qualified) property or method on* the target* @return an object that implements <code>listenerInterface</code>** @throws NullPointerException if <code>listenerInterface</code> is null* @throws NullPointerException if <code>target</code> is null* @throws NullPointerException if <code>action</code> is null** @see #create(Class, Object, String, String)*/public static <T> T create(Class<T> listenerInterface,Object target, String action){return create(listenerInterface, target, action, null, null);}/**/*** Creates an implementation of <code>listenerInterface</code> in which* <em>all</em> of the methods pass the value of the event* expression, <code>eventPropertyName</code>, to the final method in the* statement, <code>action</code>, which is applied to the <code>target</code>.* This method is implemented by calling the* more general, implementation of the <code>create</code> method with* the <code>listenerMethodName</code> taking the value <code>null</code>.* Refer to* {@link java.beans.EventHandler#create(Class, Object, String, String)* the general version of create} for a complete description of* the <code>action</code> and <code>eventPropertyName</code> parameters.* <p>* To create an <code>ActionListener</code> that sets the* the text of a <code>JLabel</code> to the text value of* the <code>JTextField</code> source of the incoming event,* you can use the following code:**<blockquote>*<pre>*EventHandler.create(ActionListener.class, label, "text", "source.text");*</pre>*</blockquote>** This is equivalent to the following code:*<blockquote>*<pre>//Equivalent code using an inner class instead of EventHandler.*new ActionListener() {* public void actionPerformed(ActionEvent event) {* label.setText(((JTextField)(event.getSource())).getText());* }*};*</pre>*</blockquote>** @param <T> the type to create* @param listenerInterface the listener interface to create a proxy for* @param target the object that will perform the action* @param action the name of a (possibly qualified) property or method on* the target* @param eventPropertyName the (possibly qualified) name of a readable property of the incoming event** @return an object that implements <code>listenerInterface</code>** @throws NullPointerException if <code>listenerInterface</code> is null* @throws NullPointerException if <code>target</code> is null* @throws NullPointerException if <code>action</code> is null** @see #create(Class, Object, String, String, String)*/public static <T> T create(Class<T> listenerInterface,Object target, String action,String eventPropertyName){return create(listenerInterface, target, action, eventPropertyName, null);}/*** Creates an implementation of <code>listenerInterface</code> in which* the method named <code>listenerMethodName</code>* passes the value of the event expression, <code>eventPropertyName</code>,* to the final method in the statement, <code>action</code>, which* is applied to the <code>target</code>. All of the other listener* methods do nothing.* <p>* The <code>eventPropertyName</code> string is used to extract a value* from the incoming event object that is passed to the target* method. The common case is the target method takes no arguments, in* which case a value of null should be used for the* <code>eventPropertyName</code>. Alternatively if you want* the incoming event object passed directly to the target method use* the empty string.* The format of the <code>eventPropertyName</code> string is a sequence of* methods or properties where each method or* property is applied to the value returned by the preceding method* starting from the incoming event object.* The syntax is: <code>propertyName{.propertyName}*</code>* where <code>propertyName</code> matches a method or* property. For example, to extract the <code>point</code>* property from a <code>MouseEvent</code>, you could use either* <code>"point"</code> or <code>"getPoint"</code> as the* <code>eventPropertyName</code>. To extract the "text" property from* a <code>MouseEvent</code> with a <code>JLabel</code> source use any* of the following as <code>eventPropertyName</code>:* <code>"source.text"</code>,* <code>"getSource.text"</code> <code>"getSource.getText"</code> or* <code>"source.getText"</code>. If a method can not be found, or an* exception is generated as part of invoking a method a* <code>RuntimeException</code> will be thrown at dispatch time. For* example, if the incoming event object is null, and* <code>eventPropertyName</code> is non-null and not empty, a* <code>RuntimeException</code> will be thrown.* <p>* The <code>action</code> argument is of the same format as the* <code>eventPropertyName</code> argument where the last property name* identifies either a method name or writable property.* <p>* If the <code>listenerMethodName</code> is <code>null</code>* <em>all</em> methods in the interface trigger the <code>action</code> to be* executed on the <code>target</code>.* <p>* For example, to create a <code>MouseListener</code> that sets the target* object's <code>origin</code> property to the incoming <code>MouseEvent</code>'s* location (that's the value of <code>mouseEvent.getPoint()</code>) each* time a mouse button is pressed, one would write:*<blockquote>*<pre>*EventHandler.create(MouseListener.class, target, "origin", "point", "mousePressed");*</pre>*</blockquote>** This is comparable to writing a <code>MouseListener</code> in which all* of the methods except <code>mousePressed</code> are no-ops:**<blockquote>*<pre>//Equivalent code using an inner class instead of EventHandler.*new MouseAdapter() {* public void mousePressed(MouseEvent e) {* target.setOrigin(e.getPoint());* }*};* </pre>*</blockquote>** @param <T> the type to create* @param listenerInterface the listener interface to create a proxy for* @param target the object that will perform the action* @param action the name of a (possibly qualified) property or method on* the target* @param eventPropertyName the (possibly qualified) name of a readable property of the incoming event* @param listenerMethodName the name of the method in the listener interface that should trigger the action** @return an object that implements <code>listenerInterface</code>** @throws NullPointerException if <code>listenerInterface</code> is null* @throws NullPointerException if <code>target</code> is null* @throws NullPointerException if <code>action</code> is null** @see EventHandler*/public static <T> T create(Class<T> listenerInterface,Object target, String action,String eventPropertyName,String listenerMethodName){// Create this first to verify target/action are non-nullfinal EventHandler handler = new EventHandler(target, action,eventPropertyName,listenerMethodName);if (listenerInterface == null) {throw new NullPointerException("listenerInterface must be non-null");}final ClassLoader loader = getClassLoader(listenerInterface);final Class<?>[] interfaces = {listenerInterface};return AccessController.doPrivileged(new PrivilegedAction<T>() {@SuppressWarnings("unchecked")public T run() {return (T) Proxy.newProxyInstance(loader, interfaces, handler);}});}private static ClassLoader getClassLoader(Class<?> type) {ReflectUtil.checkPackageAccess(type);ClassLoader loader = type.getClassLoader();if (loader == null) {loader = Thread.currentThread().getContextClassLoader(); // avoid use of BCPif (loader == null) {loader = ClassLoader.getSystemClassLoader();}}return loader;}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。