4498236: RFE: Provide a toString method for PropertyChangeEvent and other classes
authormalenkov
Thu, 18 Feb 2010 17:46:40 +0300
changeset 4960 99ac74ca2f2f
parent 4959 cbbde29076d7
child 4961 782d808b538f
4498236: RFE: Provide a toString method for PropertyChangeEvent and other classes Reviewed-by: peterz
jdk/src/share/classes/java/beans/BeanDescriptor.java
jdk/src/share/classes/java/beans/EventSetDescriptor.java
jdk/src/share/classes/java/beans/FeatureDescriptor.java
jdk/src/share/classes/java/beans/IndexedPropertyChangeEvent.java
jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java
jdk/src/share/classes/java/beans/MethodDescriptor.java
jdk/src/share/classes/java/beans/PropertyChangeEvent.java
jdk/src/share/classes/java/beans/PropertyDescriptor.java
jdk/test/java/beans/Introspector/Test4498236.java
--- a/jdk/src/share/classes/java/beans/BeanDescriptor.java	Fri Feb 12 14:38:16 2010 +0900
+++ b/jdk/src/share/classes/java/beans/BeanDescriptor.java	Thu Feb 18 17:46:40 2010 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2004 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2010 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -101,4 +101,9 @@
         beanClassRef = old.beanClassRef;
         customizerClassRef = old.customizerClassRef;
     }
+
+    void appendTo(StringBuilder sb) {
+        appendTo(sb, "beanClass", this.beanClassRef);
+        appendTo(sb, "customizerClass", this.customizerClassRef);
+    }
 }
--- a/jdk/src/share/classes/java/beans/EventSetDescriptor.java	Fri Feb 12 14:38:16 2010 +0900
+++ b/jdk/src/share/classes/java/beans/EventSetDescriptor.java	Thu Feb 18 17:46:40 2010 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2010 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
 package java.beans;
 
 import java.lang.ref.Reference;
-
 import java.lang.reflect.Method;
 
 /**
@@ -357,8 +356,7 @@
      * @return The method used to register a listener at the event source.
      */
     public synchronized Method getAddListenerMethod() {
-        return (addMethodDescriptor != null ?
-                    addMethodDescriptor.getMethod() : null);
+        return getMethod(this.addMethodDescriptor);
     }
 
     private synchronized void setAddListenerMethod(Method method) {
@@ -378,8 +376,7 @@
      * @return The method used to remove a listener at the event source.
      */
     public synchronized Method getRemoveListenerMethod() {
-        return (removeMethodDescriptor != null ?
-                    removeMethodDescriptor.getMethod() : null);
+        return getMethod(this.removeMethodDescriptor);
     }
 
     private synchronized void setRemoveListenerMethod(Method method) {
@@ -401,8 +398,7 @@
      * @since 1.4
      */
     public synchronized Method getGetListenerMethod() {
-        return (getMethodDescriptor != null ?
-                    getMethodDescriptor.getMethod() : null);
+        return getMethod(this.getMethodDescriptor);
     }
 
     private synchronized void setGetListenerMethod(Method method) {
@@ -522,4 +518,19 @@
         unicast = old.unicast;
         inDefaultEventSet = old.inDefaultEventSet;
     }
+
+    void appendTo(StringBuilder sb) {
+        appendTo(sb, "unicast", this.unicast);
+        appendTo(sb, "inDefaultEventSet", this.inDefaultEventSet);
+        appendTo(sb, "listenerType", this.listenerTypeRef);
+        appendTo(sb, "getListenerMethod", getMethod(this.getMethodDescriptor));
+        appendTo(sb, "addListenerMethod", getMethod(this.addMethodDescriptor));
+        appendTo(sb, "removeListenerMethod", getMethod(this.removeMethodDescriptor));
+    }
+
+    private static Method getMethod(MethodDescriptor descriptor) {
+        return (descriptor != null)
+                ? descriptor.getMethod()
+                : null;
+    }
 }
--- a/jdk/src/share/classes/java/beans/FeatureDescriptor.java	Fri Feb 12 14:38:16 2010 +0900
+++ b/jdk/src/share/classes/java/beans/FeatureDescriptor.java	Thu Feb 18 17:46:40 2010 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2010 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
 
 import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.Map.Entry;
 
 /**
  * The FeatureDescriptor class is the common baseclass for PropertyDescriptor,
@@ -393,4 +394,52 @@
     private String name;
     private String displayName;
     private Hashtable<String, Object> table;
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return a string representation of the object
+     *
+     * @since 1.7
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder(getClass().getName());
+        sb.append("[name=").append(this.name);
+        appendTo(sb, "displayName", this.displayName);
+        appendTo(sb, "shortDescription", this.shortDescription);
+        appendTo(sb, "preferred", this.preferred);
+        appendTo(sb, "hidden", this.hidden);
+        appendTo(sb, "expert", this.expert);
+        if ((this.table != null) && !this.table.isEmpty()) {
+            sb.append("; values={");
+            for (Entry<String, Object> entry : this.table.entrySet()) {
+                sb.append(entry.getKey()).append("=").append(entry.getValue()).append("; ");
+            }
+            sb.setLength(sb.length() - 2);
+            sb.append("}");
+        }
+        appendTo(sb);
+        return sb.append("]").toString();
+    }
+
+    void appendTo(StringBuilder sb) {
+    }
+
+    static void appendTo(StringBuilder sb, String name, Reference reference) {
+        if (reference != null) {
+            appendTo(sb, name, reference.get());
+        }
+    }
+
+    static void appendTo(StringBuilder sb, String name, Object value) {
+        if (value != null) {
+            sb.append("; ").append(name).append("=").append(value);
+        }
+    }
+
+    static void appendTo(StringBuilder sb, String name, boolean value) {
+        if (value) {
+            sb.append("; ").append(name);
+        }
+    }
 }
--- a/jdk/src/share/classes/java/beans/IndexedPropertyChangeEvent.java	Fri Feb 12 14:38:16 2010 +0900
+++ b/jdk/src/share/classes/java/beans/IndexedPropertyChangeEvent.java	Thu Feb 18 17:46:40 2010 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -62,7 +62,6 @@
         this.index = index;
     }
 
-
     /**
      * Gets the index of the property that was changed.
      *
@@ -72,4 +71,8 @@
     public int getIndex() {
         return index;
     }
+
+    void appendTo(StringBuilder sb) {
+        sb.append("; index=").append(getIndex());
+    }
 }
--- a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Fri Feb 12 14:38:16 2010 +0900
+++ b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java	Thu Feb 18 17:46:40 2010 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2010 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
 package java.beans;
 
 import java.lang.ref.Reference;
-
 import java.lang.reflect.Method;
 
 /**
@@ -117,8 +116,7 @@
      * This constructor takes the name of a simple property, and Method
      * objects for reading and writing the property.
      *
-     * @param propertyName The programmatic name of the pro
-perty.
+     * @param propertyName The programmatic name of the property.
      * @param readMethod The method used for reading the property values as an array.
      *          May be null if the property is write-only or must be indexed.
      * @param writeMethod The method used for writing the property values as an array.
@@ -518,20 +516,10 @@
         return result;
     }
 
-    /*
-    public String toString() {
-        String message = super.toString();
-
-        message += ", indexedType=";
-        message += getIndexedPropertyType();
-
-        message += ", indexedWriteMethod=";
-        message += indexedWriteMethodName;
-
-        message += ", indexedReadMethod=";
-        message += indexedReadMethodName;
-
-        return message;
+    void appendTo(StringBuilder sb) {
+        super.appendTo(sb);
+        appendTo(sb, "indexedPropertyType", this.indexedPropertyTypeRef);
+        appendTo(sb, "indexedReadMethod", this.indexedReadMethodRef);
+        appendTo(sb, "indexedWriteMethod", this.indexedWriteMethodRef);
     }
-    */
 }
--- a/jdk/src/share/classes/java/beans/MethodDescriptor.java	Fri Feb 12 14:38:16 2010 +0900
+++ b/jdk/src/share/classes/java/beans/MethodDescriptor.java	Thu Feb 18 17:46:40 2010 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2010 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,9 +27,7 @@
 
 import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
-
 import java.lang.reflect.Method;
-
 import java.util.List;
 import java.util.ArrayList;
 
@@ -167,23 +165,6 @@
     }
 
     /*
-    public String toString() {
-        String message = "name=" + getName();
-        Class cls = getClass0();
-        if (cls != null) {
-            message += ", class=";
-            message += cls.getName();
-        }
-        String[] names = getParamNames();
-        if (names != null) {
-            for (int i = 0; i < names.length; i++) {
-                message += ", param=" + names[i];
-            }
-        }
-        return message;
-        } */
-
-    /*
      * Package-private constructor
      * Merge two method descriptors.  Where they conflict, give the
      * second argument (y) priority over the first argument (x).
@@ -233,4 +214,15 @@
         }
     }
 
+    void appendTo(StringBuilder sb) {
+        appendTo(sb, "method", this.methodRef);
+        if (this.parameterDescriptors != null) {
+            sb.append("; parameterDescriptors={");
+            for (ParameterDescriptor pd : this.parameterDescriptors) {
+                sb.append(pd).append(", ");
+            }
+            sb.setLength(sb.length() - 2);
+            sb.append("}");
+        }
+    }
 }
--- a/jdk/src/share/classes/java/beans/PropertyChangeEvent.java	Fri Feb 12 14:38:16 2010 +0900
+++ b/jdk/src/share/classes/java/beans/PropertyChangeEvent.java	Thu Feb 18 17:46:40 2010 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2010 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -140,4 +140,25 @@
      * @see #getPropagationId
      */
     private Object propagationId;
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return a string representation of the object
+     *
+     * @since 1.7
+     */
+    public String toString() {
+        StringBuilder sb = new StringBuilder(getClass().getName());
+        sb.append("[propertyName=").append(getPropertyName());
+        appendTo(sb);
+        sb.append("; oldValue=").append(getOldValue());
+        sb.append("; newValue=").append(getNewValue());
+        sb.append("; propagationId=").append(getPropagationId());
+        sb.append("; source=").append(getSource());
+        return sb.append("]").toString();
+    }
+
+    void appendTo(StringBuilder sb) {
+    }
 }
--- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java	Fri Feb 12 14:38:16 2010 +0900
+++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java	Thu Feb 18 17:46:40 2010 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright 1996-2009 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 1996-2010 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
 package java.beans;
 
 import java.lang.ref.Reference;
-
 import java.lang.reflect.Method;
 import java.lang.reflect.Constructor;
 
@@ -710,22 +709,12 @@
         return baseName;
     }
 
-    /*
-    public String toString() {
-        String message = "name=" + getName();
-        message += ", class=" + getClass0();
-        message += ", type=" + getPropertyType();
-
-        message += ", writeMethod=";
-        message += writeMethodName;
-
-        message += ", readMethod=";
-        message += readMethodName;
-
-        message += ", bound=" + bound;
-        message += ", constrained=" + constrained;
-
-        return message;
+    void appendTo(StringBuilder sb) {
+        appendTo(sb, "bound", this.bound);
+        appendTo(sb, "constrained", this.constrained);
+        appendTo(sb, "propertyEditorClass", this.propertyEditorClassRef);
+        appendTo(sb, "propertyType", this.propertyTypeRef);
+        appendTo(sb, "readMethod", this.readMethodRef);
+        appendTo(sb, "writeMethod", this.writeMethodRef);
     }
-    */
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Introspector/Test4498236.java	Thu Feb 18 17:46:40 2010 +0300
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2010 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 4498236
+ * @summary Tests toString methods
+ * @author Sergey Malenkov
+ */
+
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.beans.BeanDescriptor;
+import java.beans.EventSetDescriptor;
+import java.beans.FeatureDescriptor;
+import java.beans.IndexedPropertyChangeEvent;
+import java.beans.IndexedPropertyDescriptor;
+import java.beans.MethodDescriptor;
+import java.beans.ParameterDescriptor;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+
+public class Test4498236 {
+
+    public static void main(String[] args) throws Exception {
+        PropertyChangeEvent event = new PropertyChangeEvent("source", null, null, null);
+        event.setPropagationId("id");
+        test("[propertyName=null; oldValue=null; newValue=null; propagationId=id; source=source]", event);
+        test("[propertyName=name; oldValue=old; newValue=new; propagationId=null; source=source]",
+             new PropertyChangeEvent("source", "name", "old", "new")
+        );
+        test("[propertyName=array; index=5; oldValue=old; newValue=new; propagationId=null; source=source]",
+             new IndexedPropertyChangeEvent("source", "array", "old", "new", 5)
+        );
+        FeatureDescriptor fd = new FeatureDescriptor();
+        fd.setName("n");
+        fd.setDisplayName("dn");
+        fd.setShortDescription("sd");
+        fd.setPreferred(true);
+        fd.setHidden(true);
+        fd.setExpert(true);
+        fd.setValue("first", "value");
+        test("[name=n; displayName=dn; shortDescription=sd; preferred; hidden; expert; values={first=value}]", fd);
+        test("[name=String; beanClass=class java.lang.String]",
+             new BeanDescriptor(String.class)
+        );
+        test("[name=Object; beanClass=class java.lang.Object; customizerClass=class java.lang.String]",
+             new BeanDescriptor(Object.class, String.class)
+        );
+        test("[name=Object; beanClass=class java.lang.Object; customizerClass=class java.lang.String]",
+             new BeanDescriptor(Object.class, String.class)
+        );
+        test("[name=equals; method=public boolean java.lang.Object.equals(java.lang.Object)]",
+             new MethodDescriptor(Object.class.getMethod("equals", Object.class))
+        );
+        test("[name=equals; method=public boolean java.lang.Object.equals(java.lang.Object); parameterDescriptors={java.beans.ParameterDescriptor[name=null]}]",
+             new MethodDescriptor(Object.class.getMethod("equals", Object.class), new ParameterDescriptor[] {
+                     new ParameterDescriptor()
+             })
+        );
+        Class type = KeyListener.class;
+        String[] names = { "keyTyped", "keyPressed", "keyReleased" };
+        Method[] methods = new Method[names.length];
+        for (int i = 0; i < names.length; i++) {
+            methods[i] = type.getMethod(names[i], KeyEvent.class);
+        }
+        test("[name=key; inDefaultEventSet; listenerType=interface java.awt.event.KeyListener; getListenerMethod=public java.awt.event.KeyListener Test4498236.getKeyListeners(); addListenerMethod=public void Test4498236.addKeyListener(java.awt.event.KeyListener); removeListenerMethod=public void Test4498236.removeKeyListener(java.awt.event.KeyListener)]",
+             new EventSetDescriptor(Test4498236.class, "key", type, names[0])
+        );
+        test("[name=$$$; inDefaultEventSet; listenerType=interface java.awt.event.KeyListener; addListenerMethod=public void Test4498236.add(java.awt.event.KeyListener); removeListenerMethod=public void Test4498236.remove(java.awt.event.KeyListener)]",
+             new EventSetDescriptor(Test4498236.class, "$$$", type, names, "add", "remove")
+        );
+        test("[name=$$$; inDefaultEventSet; listenerType=interface java.awt.event.KeyListener; getListenerMethod=public java.awt.event.KeyListener Test4498236.get(); addListenerMethod=public void Test4498236.add(java.awt.event.KeyListener); removeListenerMethod=public void Test4498236.remove(java.awt.event.KeyListener)]",
+             new EventSetDescriptor(Test4498236.class, "$$$", type, names, "add", "remove", "get")
+        );
+        test("[name=$$$; inDefaultEventSet; listenerType=interface java.awt.event.KeyListener; addListenerMethod=public void Test4498236.add(java.awt.event.KeyListener); removeListenerMethod=public void Test4498236.remove(java.awt.event.KeyListener)]",
+             new EventSetDescriptor("$$$", type, methods, Test4498236.class.getMethod("add", type), Test4498236.class.getMethod("remove", type))
+        );
+        test("[name=$$$; inDefaultEventSet; listenerType=interface java.awt.event.KeyListener; getListenerMethod=public java.awt.event.KeyListener Test4498236.get(); addListenerMethod=public void Test4498236.add(java.awt.event.KeyListener); removeListenerMethod=public void Test4498236.remove(java.awt.event.KeyListener)]",
+             new EventSetDescriptor("$$$", type, methods, Test4498236.class.getMethod("add", type), Test4498236.class.getMethod("remove", type), Test4498236.class.getMethod("get"))
+        );
+        test("[name=value; propertyType=boolean; readMethod=public boolean Test4498236.isValue(); writeMethod=public void Test4498236.setValue(boolean)]",
+             new PropertyDescriptor("value", Test4498236.class)
+        );
+        test("[name=$$$]",
+             new PropertyDescriptor("$$$", Test4498236.class, null, null)
+        );
+        test("[name=$$$; propertyType=boolean; readMethod=public boolean Test4498236.getValue()]",
+             new PropertyDescriptor("$$$", Test4498236.class, "getValue", null)
+        );
+        test("[name=$$$; propertyType=boolean; readMethod=public boolean Test4498236.getValue(); writeMethod=public void Test4498236.setValue(boolean)]",
+             new PropertyDescriptor("$$$", Test4498236.class, "getValue", "setValue")
+        );
+        test("[name=$$$]",
+             new PropertyDescriptor("$$$", null, null)
+        );
+        test("[name=$$$; propertyType=boolean; readMethod=public boolean Test4498236.getValue()]",
+             new PropertyDescriptor("$$$", Test4498236.class.getMethod("getValue"), null)
+        );
+        test("[name=$$$; propertyType=boolean; readMethod=public boolean Test4498236.getValue(); writeMethod=public void Test4498236.setValue(boolean)]",
+             new PropertyDescriptor("$$$", Test4498236.class.getMethod("getValue"), Test4498236.class.getMethod("setValue", boolean.class))
+        );
+        test("[name=index; propertyType=class [I; readMethod=public int[] Test4498236.getIndex(); writeMethod=public void Test4498236.setIndex(int[]); indexedPropertyType=int; indexedReadMethod=public int Test4498236.getIndex(int); indexedWriteMethod=public void Test4498236.setIndex(int,int)]",
+             new IndexedPropertyDescriptor("index", Test4498236.class)
+        );
+        test("[name=$$$; propertyType=class [I; readMethod=public int[] Test4498236.getIndex(); writeMethod=public void Test4498236.setIndex(int[]); indexedPropertyType=int; indexedReadMethod=public int Test4498236.getIndex(int); indexedWriteMethod=public void Test4498236.setIndex(int,int)]",
+             new IndexedPropertyDescriptor("$$$", Test4498236.class, "getIndex", "setIndex", "getIndex", "setIndex")
+        );
+        test("[name=$$$; propertyType=class [I; readMethod=public int[] Test4498236.getIndex(); writeMethod=public void Test4498236.setIndex(int[]); indexedPropertyType=int; indexedReadMethod=public int Test4498236.getIndex(int); indexedWriteMethod=public void Test4498236.setIndex(int,int)]",
+             new IndexedPropertyDescriptor("$$$", Test4498236.class.getMethod("getIndex"), Test4498236.class.getMethod("setIndex", new int[0].getClass()), Test4498236.class.getMethod("getIndex", int.class), Test4498236.class.getMethod("setIndex", int.class, int.class) )
+        );
+    }
+
+    public void addKeyListener(KeyListener listener) {
+        add(listener);
+    }
+
+    public void removeKeyListener(KeyListener listener) {
+        remove(listener);
+    }
+
+    public KeyListener getKeyListeners() {
+        return null;
+    }
+
+    public void add(KeyListener listener) {
+    }
+
+    public void remove(KeyListener listener) {
+    }
+
+    public KeyListener get() {
+        return null;
+    }
+
+    public boolean isValue() {
+        return true;
+    }
+
+    public boolean getValue() {
+        return true;
+    }
+
+    public void setValue(boolean value) {
+    }
+
+    public int[] getIndex() {
+        return null;
+    }
+
+    public int getIndex(int index) {
+        return 0;
+    }
+
+    public void setIndex(int index, int value) {
+    }
+
+    public void setIndex(int[] value) {
+    }
+
+    private static void test(String expected, Object object) {
+        String actual = object.toString();
+        if (!actual.equals(object.getClass().getName() + expected)) {
+            throw new Error(actual);
+        }
+    }
+}