From: Edwin C. <com...@gm...> - 2009-08-12 20:41:23
|
Hi Ying Xia, Thanks for diving into the code, and good to hear you like the setProperty/getProperty idea. The package name was intentionally changed to org.gwtopenmaps.openlayers vs org.openlayers, so we could some day move GWT utility stuff out to org.gwtopenmaps.commons or something like that. I guess GWT doesn't include that stuff, because the real power of GWT is when you use native GWT vs native javascript, but truly porting OpenLayers would be a very big job! I now understand the idea of your code is not to "set a function" on a JSObject, but to "call a function" on a JSObject. The latter means that the function should already be defined on the object in Javascript. That is actually an interesting idea. I can image that JSObject offers a method "invoke" which calls a function on the javascript object represented by JSObject. I will try that out and see if how it works out in GWT-OL. One first thing that comes to mind is what to do with functions that return values. If invoke is generic it will probably return JSObject (maybe have an "invokeVoid" for functions that do not return values, and "invoke" for functions that return values). I am always a bit hazy on how good casting works in GWT. Anyway, I will play around with it. In GWT-OL the name "wrapper" is used for classes that keep a reference to the object they wrap, and that delegate method invocations to wrapped object reference. For example JSObjectWrapper has a JSObject property. Methods exposed by a class that extends JSObjectWrapper are eventually called on the JSObject. To my mind, your JavaScriptObjectWrapper is actually extending JavaScriptObject, rather than wrapping it, but that is just a difference in terminology. Greetings and thanks for thinking with us, Edwin 2009/8/12 岚山.隐 <642...@qq...> > I spend hours to see the source code of the project. I think it is very > cool when I saw the encapsulated methods "setProperty" and "getPropertyAs*" > which makes all set and get javascript property code come to one place. > Then I think about for minutes, if property can, why not method! So I > started to encapsulate method just as how you have done on property. > The following is my code, whether it could be used on this project? I think > that piece this together with the JSObject class will disappear all the > "*Impl" classes in this project. > > > package com.yingxia.client.jsni; > > import com.google.gwt.core.client.JavaScriptObject; > > public class JavaScriptObjectWrapper extends JavaScriptObject { > > protected JavaScriptObjectWrapper() { > } > > public static native JavaScriptObjectWrapper createNew() /*-{ > return {}; > }-*/; > > public final JavaScriptObjectWrapper invokeJSMethod(String methodName, > Object... objs) { > JavaScriptObjectWrapper arguments = > JavaScriptArrayHelper.toJSArray(objs); > return JavaScriptObjectWrapperImpl.invokeJSMethod(this, methodName, > arguments); > } > > } > > package com.yingxia.client.jsni; > > public class JavaScriptObjectWrapperImpl { > > public static native JavaScriptObjectWrapper > invokeJSMethod(JavaScriptObjectWrapper jsObject, String methodName, > JavaScriptObjectWrapper arguments) /*-{ > return jsObject[methodName].apply(jsObject, arguments); > }-*/; > > } > > package com.yingxia.client.jsni; > > public class JavaScriptArrayHelper { > /** > * > * @param objs : must be primitive type or JavaScriptObject, now just > support few you can extend > * @return > */ > public static JavaScriptObjectWrapper toJSArray(Object... objs) { > > JavaScriptObjectWrapper jsArray = createJSArray(); > > for(int i = 0; i < objs.length; i++) { > setJSArray(jsArray, i, objs[i]); > } > > return jsArray; > } > > private static native JavaScriptObjectWrapper createJSArray() /*-{ > return []; > }-*/; > > private static void setJSArray(JavaScriptObjectWrapper jsArray, int index, > Object value) { > if(value.getClass().equals(java.lang.Integer.class)) { > setJSArray(jsArray, index, (int) Integer.valueOf(value.toString())); > } > if(value.getClass().equals(java.lang.Float.class)) { > setJSArray(jsArray, index, (float) Float.valueOf(value.toString())); > } > if(value.getClass().equals(java.lang.Double.class)) { > setJSArray(jsArray, index, (double) Double.valueOf(value.toString())); > } > if(value.getClass().equals(java.lang.Boolean.class)) { > setJSArray(jsArray, index, (boolean) Boolean.valueOf(value.toString())); > } > if(value.getClass().equals(java.lang.String.class)) { > setJSArray(jsArray, index, value.toString()); > } > if(value.getClass().equals(JavaScriptObjectWrapper.class)) { > setJSArray(jsArray, index, (JavaScriptObjectWrapper) value); > } > } > > private static native void setJSArray(JavaScriptObjectWrapper jsArray, int > index, int value) /*-{ > jsArray[index] = value; > }-*/; > > private static native void setJSArray(JavaScriptObjectWrapper jsArray, int > index, float value) /*-{ > jsArray[index] = value; > }-*/; > > private static native void setJSArray(JavaScriptObjectWrapper jsArray, int > index, double value) /*-{ > jsArray[index] = value; > }-*/; > > private static native void setJSArray(JavaScriptObjectWrapper jsArray, int > index, boolean value) /*-{ > jsArray[index] = value; > }-*/; > > private static native void setJSArray(JavaScriptObjectWrapper jsArray, int > index, String value) /*-{ > jsArray[index] = value; > }-*/; > > private static native void setJSArray(JavaScriptObjectWrapper jsArray, int > index, JavaScriptObjectWrapper value) /*-{ > jsArray[index] = value; > }-*/; > } > > > Greetings, > ying xia > |