/* * SmartGWT (GWT for SmartClient) * Copyright 2008 and beyond, Isomorphic Software, Inc. * * SmartGWT is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3 * as published by the Free Software Foundation. SmartGWT is also * available under typical commercial license terms - see * http://smartclient.com/license * * 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. */ package com.smartgwt.client.widgets; import java.util.Date; import java.util.Map; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.GwtEvent; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.event.shared.HasHandlers; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Widget; import com.smartgwt.client.bean.BeanFactory; import com.smartgwt.client.core.BaseClass; import com.smartgwt.client.core.DataClass; import com.smartgwt.client.core.Function; import com.smartgwt.client.core.LogicalStructure; import com.smartgwt.client.core.NativeObject; import com.smartgwt.client.data.Record; import com.smartgwt.client.types.ValueEnum; import com.smartgwt.client.util.IDManager; import com.smartgwt.client.util.JSOHelper; import com.smartgwt.client.util.SC; import com.smartgwt.client.widgets.events.DrawEvent; import com.smartgwt.client.widgets.events.DrawHandler; import com.smartgwt.logicalstructure.core.LogicalStructureObject; import com.smartgwt.logicalstructure.widgets.BaseWidgetLogicalStructure; public abstract class BaseWidget extends Widget implements HasHandlers, LogicalStructure { private Function onRenderFn; static { init(); } private static String FALSE_PLACEHOLDER; private static native void init()/*-{ $wnd.isc.setAutoDraw(false); @com.smartgwt.client.widgets.BaseWidget::FALSE_PLACEHOLDER = new String("false"); }-*/; protected String id; protected JavaScriptObject config = JSOHelper.createObject(); protected String scClassName; protected boolean configOnly; // Properties stashed by BeanFactory when calling the no-arg constructor. // We pick them up immediately in the constructor so that they don't get // applied to the wrong object (in case the constructor of a subclass // triggers the construction of some other object). Fortunately, our // constructor is called first! The properties get applied when // getOrCreateJsObj() is called (checked below), or when all constructors // have finished (checked by BeanFactory), whichever comes first. protected Map<String, Object> factoryProperties; // Tracks whether this object was created by a BeanFactory. The BeanFactory // code will set this property via the reflection mechanism when creating // an instance. Thus, it can check whether the property has been correctly // applied. (That is, if factoryCreated is false for an object which // BeanFactory creates, then BeanFactory knows something went wrong). // // There is one known case where properties are not correctly applied via // reflection: when (a) a class has a static initializer; (b) the static // initializer is not triggered before the use of reflection to create an // object of that class; and (c) the static initializer itself creates an // object of that class. // // We can't detect that case directly, but we can at least detect the // resulting failure and try to recover (and generate a useful error // message). protected boolean factoryCreated; public void setFactoryCreated (boolean createdByBeanFactory) { factoryCreated = createdByBeanFactory; } public boolean isFactoryCreated () { return factoryCreated; } /** * Adds this handler to the widget. * * @param <H> the type of handler to add * @param type the event type * @param handler the handler * @return {@link HandlerRegistration} used to remove the handler */ protected final <H extends EventHandler> HandlerRegistration doAddHandler(final H handler, GwtEvent.Type<H> type) { return addHandler(handler, type); } public int getHandlerCount(GwtEvent.Type<?> type) { return super.getHandlerCount(type); }; public BaseWidget() { // We immediately pick up any properties which BeanFactory has stashed. // We can't pick them up later (for instance, at getOrCreateJsObj() // time), because the constructor could create *other* objects first // and trigger getOrCreateJsObj() on them -- in which case, the global // would be applied to the wrong object. So, we need to pick up the // global at the earliest moment after the constructor is called -- // which is here, since superclass constructors get called before // subclass constructors. // // We only need to deal with the no-arg constructor because that is the // one which BeanFactory uses. An alternative would be to use a // constructor which takes a JavaScriptObject, but that would mean that // developers would need to implement that constructor for custom // classes, and it's undesirable to force them to do so. // // We don't apply the properties immediately, because we're at the very // beginning of the base class constructor -- the setters may rely on // further construction having taken place. So we delay as long as // possible -- either until getOrCreateJsObj() is called, or the object // is fully constructed, whichever comes first. // // We test the factoryPropertiesClass to avoid applying properties // intended for a different class. This can occur if a static // initializer creates objects, since the static initializer can run // after the properties are stashed but before the constructor runs. // Checking the factoryPropertiesClass at least limits the problem to // cases where the static initializer creates objects of the same class. if (getClass() == BeanFactory.getFactoryPropertiesClass()) { factoryProperties = BeanFactory.getFactoryProperties(); BeanFactory.clearFactoryProperties(); } } public BaseWidget(String id) { setID(id); } public void setJavaScriptObject(JavaScriptObject jsObj) { internalSetID(jsObj); JSOHelper.setObjectAttribute(jsObj, SC.REF, this); JSOHelper.setObjectAttribute(jsObj, SC.MODULE, BeanFactory.getSGWTModule()); if (!JSOHelper.isScClassInstance(jsObj)) { setConfig(jsObj); return; } JSOHelper.setObjectAttribute(getConfig(), SC.REF, this); JSOHelper.setObjectAttribute(getConfig(), SC.MODULE, BeanFactory.getSGWTModule()); onBind(); } public static BaseWidget getRef(JavaScriptObject jsObj) { if (jsObj == null) { return null; } else { final Object ref = JSOHelper.getAttributeAsObject((JavaScriptObject)jsObj, SC.REF); if (ref == null || !(ref instanceof BaseWidget)) { return null; } else { return (BaseWidget)ref; } } } public static boolean hasAutoAssignedID(JavaScriptObject jsObj) { return jsObj == null ? false : JSOHelper.getAttributeAsBoolean(jsObj, SC.AUTOID); } /** * Returns the javascript class name. * @return */ public String getClassName(){ return JSOHelper.getClassName(config); } /** * Get the name of the underlying SmartClient class * * @return the SmartClient class name */ public String getScClassName() { return scClassName; } /** * Set the name of the underlying SmartClient class. This is an advanced setting. * * @param scClassName the SmartClient class */ public void setScClassName(String scClassName) { this.scClassName = scClassName; } private native void wrapDestroy() /*-{ var self = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); if (self == null) { var config = this.@com.smartgwt.client.widgets.BaseWidget::getConfig()(); $wnd.isc.logWarn("wrapDestroy(): the JavaScriptObject is null unexpectedly for " + $wnd.isc.echo(config) + " with " + this.@java.lang.Object::getClass()() + ". This may lead to an ID collision after the widget is destroy()ed."); return; } if (self.__sgwtDestroy == null) self.__sgwtDestroy = function () { var jObj = this.__ref; if (jObj != null) jObj.@com.smartgwt.client.widgets.BaseWidget::destroy()(); } }-*/; protected final native void doInit()/*-{ var self = this.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()(); self.__setDragTracker = self.setDragTracker; self.setDragTracker = function() { var jObj = this.__ref; return jObj.@com.smartgwt.client.widgets.BaseWidget::setDragTracker()(); }; self.__getInnerHTML = self.getInnerHTML; self.getInnerHTML = function() { var jObj = this.__ref; this.__getInnerHTMLArguments = arguments; try { var ret = jObj.@com.smartgwt.client.widgets.BaseWidget::getInnerHTML()(); if (ret === @com.smartgwt.client.widgets.BaseWidget::FALSE_PLACEHOLDER) { return false; } else { // Call "String(...)" [note this is not the constructor "new String(...)"] // This will ensure we map any String object to the primitive // (Equivalent to calling someStringObject.valueOf()). This makes sure our // SmartClient String extensions get applied as necessary downstream. return ret == null ? null : String(ret); } } finally { this.__getInnerHTMLArguments = null; } }; if (self.shouldRedrawOnResize == $wnd.isc.Canvas.getPrototype().shouldRedrawOnResize) { self.shouldRedrawOnResize = function(deltaX, deltaY) { var redrawOnResize = self.redrawOnResize; if (redrawOnResize == null) { redrawOnResize = !((self.children != null && self.children.length > 0 && !self.allowContentAndChildren) || // we want to redrawOnResize if we have dynamic content // Check for getInnerHTML() having been overridden for this (javascript) Canvas subclass // This handles SC subclasses (EG detailViewer) where redrawOnResize is required. // If the developer overrides the java getInnerHTML() method rely on them // explicitly setting redrawOnResize if required. (self.__getInnerHTML == $wnd.isc.Canvas.getPrototype().getInnerHTML && !$wnd.isc.isA.Function(self.contents))); } return redrawOnResize; } } // onDraw() - undocumented method called from draw() as a draw-complete notification // Override this rather than overriding draw() directly - the latter adds a layer to the // stack depth on draw and when drawing deeply nested layouts etc increases the likelyhood // of seeing an out of stack depth error in IE7 and 8 self.onDraw = function () { var jObj = this.__ref; if (jObj != null) jObj.@com.smartgwt.client.widgets.BaseWidget::rendered()(); } this.@com.smartgwt.client.widgets.BaseWidget::wrapDestroy()(); this.@com.smartgwt.client.widgets.BaseWidget::onInit()(); }-*/; protected void onInit() {} // install callbacks for a live SC widget protected void onBind() { wrapDestroy(); } public boolean isConfigOnly() { return configOnly; } public void setConfigOnly(boolean configOnly) { this.configOnly = configOnly; } protected native boolean setDragTracker() /*-{ var self = this.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()(); return !!self.__setDragTracker(); }-*/; /** * Return the inner HTML for this canvas. Called when the canvas is drawn or redrawn; * override to customize. * <p> * <b>Note</b> : {@link Canvas#setRedrawOnResize} should be set to true for components whose inner HTML * will not automatically reflow to fit the component's new size. * * @return HTML contents of this canvas */ public native String getInnerHTML() /*-{ var self = this.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()(); var ret = self.__getInnerHTML.apply(self, self.__getInnerHTMLArguments); if (ret === false) { ret = @com.smartgwt.client.widgets.BaseWidget::FALSE_PLACEHOLDER; } return ret; }-*/; /** * Draws the widget on the page. */ public native void draw() /*-{ if (this.@com.smartgwt.client.widgets.BaseWidget::isConfigOnly()()) { @com.smartgwt.client.util.ConfigUtil::warnOfPostConfigInstantiation(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;)(this.@java.lang.Object::getClass()(), "draw", ""); } var self = this.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()(); self.draw(); }-*/; /** * Permanently destroy a Canvas and all of it's children / members, recursively. * <P> * Like {@link Canvas#clear()} calling <code>destroy()</code> removes all HTML for the component; * unlike clear(), a destroyed Canvas is permanently unusable: it cannot be draw()'n again and * cannot be referenced by its global ID. This method also removes all JavaScript references to * the Canvas outside of application code, making it eligible for garbage collection (though * developers will need to release any references to the canvas held in application code themselves). * <P> * Any attempt to call a method on a destroyed Canvas will generally result in an error. If your * application is forced to hold onto Canvas's that might be destroy()d without warning, you can * avoid errors by checking for the {@link Canvas#getDestroyed()} property. If you override certain Canvas * methods, your code may be called while a Canvas is being destroy()d; in this case you can avoid * extra work (and possibly errors) by checking for the +{@link Canvas#getDestroying()} property. * <P> * Note that <code>destroy()</code> should not be called directly in event handling code for this * canvas. For this reason, wherever possible we recommend using {@link Canvas#markForDestroy()} * instead of calling this method directly. * <P> * <b>Note</b>: This is an override point */ public native void destroy() /*-{ var self = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); if (self != null && self.__sgwtDestroy) { delete self.__sgwtDestroy; if (self.destroy) self.destroy(); } var id = this.@com.smartgwt.client.widgets.BaseWidget::id; if (id != null) { this.@com.smartgwt.client.widgets.BaseWidget::clearID()(); this.@com.smartgwt.client.widgets.Canvas::onDestroy()(); } this.@com.smartgwt.client.widgets.BaseWidget::clearConfigRef()(); }-*/; private void clearID() { IDManager.unregisterID(this, this.id); this.id = null; JSOHelper.setNullAttribute(config, SC.AUTOIDCLASS); JSOHelper.setNullAttribute(config, "ID"); JSOHelper.setNullAttribute(config, SC.AUTOID); } private void clearConfigRef() { JSOHelper.setNullAttribute(this.config, SC.REF); JSOHelper.setNullAttribute(this.config, SC.MODULE); } public void doOnRender(Function function) { onRenderFn = function; } private void rendered() { onDraw(); fireEvent(new DrawEvent(getID())); if (onRenderFn != null) { onRenderFn.execute(); } } public HandlerRegistration addDrawHandler(DrawHandler handler) { setupDrawHandlerEvent(); return doAddHandler(handler, DrawEvent.getType()); } private native void setupDrawHandlerEvent() /*-{ var obj = null; var selfJ = this; var drawn = $entry(function(){ selfJ.@com.smartgwt.client.widgets.BaseWidget::rendered()(); }); if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { obj = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); obj.addProperties({onDraw: drawn}); } else { obj = this.@com.smartgwt.client.widgets.BaseWidget::getConfig()(); obj.onDraw = drawn; } }-*/; protected void onDraw() { } protected void onDestroy() { } public void setPosition(String position) { setAttribute("position", position, false); } public void setHtmlElement(Element element) { setAttribute("htmlElement", element, false); } public native Element getDOM()/*-{ var widget = this.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()(); return widget.getHandle(); }-*/; public String getID() { if (id == null) { // Generate an ID because one was requested by the caller. final String className = SC.getAUTOIDClass(getClass().getName()); setAttribute("AUTOIDClass", className, false); internalSetID(SC.generateID(className), true); } assert id != null; return id; } protected final void internalSetID(JavaScriptObject jsObj) { if (this.id != null) { IDManager.unregisterID(this, this.id); } String id = JSOHelper.getAttribute (jsObj, "ID"); if (this.id != null && !this.id.equals(id) && getAttributeAsBoolean(SC.AUTOID)) { SC.releaseID(getClass().getName(), this.id); } String className = JSOHelper.getAttribute(jsObj, SC.AUTOIDCLASS); boolean auto = JSOHelper.getAttributeAsBoolean(jsObj, SC.AUTOID); IDManager.registerID(this, id, true); if (id != null) this.id = id; JSOHelper.setAttribute(config, SC.AUTOIDCLASS, className); JSOHelper.setAttribute(config, "ID", id); JSOHelper.setAttribute(config, SC.AUTOID, auto); } protected final void internalSetID(String id, boolean autoAssigned) { // prevent transaction from being started if it cannot complete successfully if (isCreated()) { error("Attempt to call internalSetID to change id from " + this.id + " to " + id + " after the SC widget has already been created"); return; } if (this.id != null) { IDManager.unregisterID(this, this.id); } IDManager.registerID(this, id, false); // If we previously auto-assigned an ID, release the ID back to SmartClient if the new // ID is different. if (this.id != null && !this.id.equals(id) && getAttributeAsBoolean(SC.AUTOID)) { SC.releaseID(getClass().getName(), this.id); } this.id = id; setAttribute( "ID", id, false); setAttribute(SC.AUTOID, autoAssigned, false); if (!autoAssigned) setAttribute(SC.AUTOIDCLASS, (String)null, false); } public void setID(String id) { internalSetID(id, false); } public JavaScriptObject getConfig() { return config; } public void setConfig(JavaScriptObject config) { this.config = config; } public native boolean isCreated()/*-{ var id = this.@com.smartgwt.client.widgets.BaseWidget::id; var obj; return id != null && (obj = $wnd.window[id]) != null && obj !== undefined && $wnd.isc.isA.Canvas(obj) === true; }-*/; protected Boolean isDrawn() { return isCreated() && doIsDrawn(); } private native boolean doIsDrawn()/*-{ var widget = this.@com.smartgwt.client.widgets.BaseWidget::getOrCreateJsObj()(); return widget.isDrawn(); }-*/; public native JavaScriptObject getJsObj()/*-{ var id = this.@com.smartgwt.client.widgets.BaseWidget::id; if (id != null && $wnd.window[id] != null && $wnd.window[id] !== undefined) { return $wnd.window[id]; } else { return null; } }-*/; public JavaScriptObject getOrCreateJsObj() { if (!isCreated()) { if (id == null) { final String className = SC.getAUTOIDClass(getClass().getName()); setAttribute("AUTOIDClass", className, false); internalSetID(SC.generateID(className), true); } // The SC.REF property will already be set if new was called on a SmartClient // JS properties object; warn here if we actually attempt to create() it. if (getRef(config) == this) { SC.logWarn("Instantiating in SGWT a properties object from the SmartClient " + "side may lead to undefined behavior if the SmartClient Framework " + "is expecting to perform the instantiation itself."); } else { JSOHelper.setObjectAttribute(config, SC.REF, this); JSOHelper.setObjectAttribute(config, SC.MODULE, BeanFactory.getSGWTModule()); } // Apply the properties provided by BeanFactory if they haven't // already been applied. We do this before calling create(), since // the constructor on the SmartClient side may be expecting some // of these properties. applyFactoryProperties(); JavaScriptObject jsObj = create(); return jsObj; } else { return getJsObj(); } } protected native JavaScriptObject create()/*-{ var config = this.@com.smartgwt.client.widgets.BaseWidget::getConfig()(); return $wnd.isc.Canvas.create(config); }-*/; // Apply any properties provided by BeanFactory before it called the no-arg // constructor. We call this before constructing the jsObj. Otherwise, the // constructor on the SmartClient side may be missing some properties it // expected to be supplied. If all the SmartGWT constructors finish and // getOrCreateJsObj() hasn't been triggered yet, then BeanFactory will call // this with the fully-constructed object. // // Note that the factoryProperties may be a mix of values that will be // passed through to the config object (either because there is no SmartGWT // setter or because that's what the SmartGWT setter does), and values // which are actually handled by SmartGWT itself. In principle, we could // delay applying the latter until later, but we can't really tell one from // the other, especially for developer subclasses. public void applyFactoryProperties () { if (factoryProperties != null) { // Make sure that this is re-entrant without infinite loop Map<String, Object> properties = factoryProperties; factoryProperties = null; BeanFactory.setProperties(this, properties); } } public String getAttribute(String attribute) { return getAttributeAsString(attribute); } protected native String getAttributeAsString(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } return ret == null || ret === undefined ? null : String(ret) ; }-*/; protected native String[] getAttributeAsStringArray(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } return ret === undefined ? null : @com.smartgwt.client.util.JSOHelper::convertToJavaStringArray(Lcom/google/gwt/core/client/JavaScriptObject;)(ret); }-*/; protected native int[] getAttributeAsIntArray(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } return ret === undefined ? null : @com.smartgwt.client.util.JSOHelper::convertToJavaIntArray(Lcom/google/gwt/core/client/JavaScriptObject;)(ret); }-*/; protected native Float[] getAttributeAsFloatArray(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } return ret === undefined ? null : @com.smartgwt.client.util.JSOHelper::convertToJavaFloatArray(Lcom/google/gwt/core/client/JavaScriptObject;)(ret); }-*/; protected native Date getAttributeAsDate(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } return ret == null || ret === undefined ? null : @com.smartgwt.client.util.JSOHelper::toDate(D)(ret.getTime()); }-*/; protected native Date[] getAttributeAsDateArray(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } if (!$wnd.isc.isA.Array(ret)) return null; return @com.smartgwt.client.util.JSOHelper::convertToJavaDateArray(Lcom/google/gwt/core/client/JavaScriptObject;)(ret); }-*/; protected native Integer getAttributeAsInt(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } return ret == null || ret === undefined ? null : @com.smartgwt.client.util.JSOHelper::toInteger(I)(ret); }-*/; protected native Double getAttributeAsDouble(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } return ret == null || ret === undefined ? null : @com.smartgwt.client.util.JSOHelper::toDouble(D)(ret); }-*/; protected native Element getAttributeAsElement(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } return ret === undefined ? null : ret; }-*/; protected native JavaScriptObject getAttributeAsJavaScriptObject(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } return ret === undefined ? null : ret; }-*/; protected native Float getAttributeAsFloat(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } return ret == null || ret === undefined ? null : @com.smartgwt.client.util.JSOHelper::toFloat(F)(ret); }-*/; protected native Boolean getAttributeAsBoolean(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } return ret == null || ret === undefined ? null : @com.smartgwt.client.util.JSOHelper::toBoolean(Z)(ret); }-*/; protected native Map getAttributeAsMap(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } return ret == null || ret === undefined ? null : @com.smartgwt.client.util.JSOHelper::convertToMap(Lcom/google/gwt/core/client/JavaScriptObject;)(ret); }-*/; protected native Record getAttributeAsRecord(String property)/*-{ var ret; if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); ret = widget.getProperty(property); } else { var config = this.@com.smartgwt.client.widgets.BaseWidget::config; if(config[property] !== undefined) { ret = config[property]; } else { var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName; ret = $wnd.isc[scClassName].getInstanceProperty(property); } } return ret == null || ret === undefined ? null : @com.smartgwt.client.data.Record::getOrCreateRef(Lcom/google/gwt/core/client/JavaScriptObject;)(ret); }-*/; private void error(String attribute, String value) throws IllegalStateException { error("Cannot change configuration property '" + attribute + "' to " + value + " now that component " + id + " has been created."); } protected void errorIfNotCreated(String property) throws IllegalStateException { if (!isCreated()) { throw new IllegalStateException("Cannot access property " + property + " before the widget has been created."); } } protected void error(String message) throws IllegalStateException { if (!GWT.isScript()) { Window.alert("Error :" + message); throw new IllegalStateException(message); } else { SC.logWarn(message); } } protected void setAttribute(String attribute, String value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value); } else if (allowPostCreate) { setProperty(attribute, value); } else { error(attribute, value); } } protected void setAttribute(String attribute, ValueEnum value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value.getValue()); } else if (allowPostCreate) { setProperty(attribute, value.getValue()); } else { error(attribute, value.getValue()); } } protected void setAttribute(String attribute, BaseWidget value, boolean allowPostCreate) { JavaScriptObject valueJS = value.isConfigOnly() ? value.getConfig() : value.getOrCreateJsObj(); if (!isCreated()) { JSOHelper.setAttribute(config, attribute, valueJS); } else if (allowPostCreate) { setProperty(attribute, valueJS); } else { error(attribute, value.toString()); } } protected void setAttribute(String attribute, Map value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value); } else if (allowPostCreate) { setProperty(attribute, JSOHelper.convertMapToJavascriptObject(value)); } else { error(attribute, value.toString()); } } protected void setAttribute(String attribute, int[] value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value); } else if (allowPostCreate) { setProperty(attribute, JSOHelper.convertToJavaScriptArray(value)); } else { error(attribute, value.toString()); } } protected void setAttribute(String attribute, float[] value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value); } else if (allowPostCreate) { setProperty(attribute, JSOHelper.convertToJavaScriptArray(value)); } else { error(attribute, value.toString()); } } protected void setAttribute(String attribute, double[] value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value); } else if (allowPostCreate) { setProperty(attribute, JSOHelper.convertToJavaScriptArray(value)); } else { error(attribute, value.toString()); } } protected void setAttribute(String attribute, Float[] value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value); } else if (allowPostCreate) { setProperty(attribute, JSOHelper.convertToJavaScriptArray(value)); } else { error(attribute, value.toString()); } } protected void setAttribute(String attribute, DataClass value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value.getJsObj()); } else if (allowPostCreate) { setProperty(attribute, value.getJsObj()); } else { error(attribute, value.toString()); } } protected void setAttribute(String attribute, DataClass[] value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, JSOHelper.convertToJavaScriptArray(value)); } else if (allowPostCreate) { setProperty(attribute, JSOHelper.convertToJavaScriptArray(value)); } else { error(attribute, value.toString()); } } protected void setAttribute(String attribute, JavaScriptObject[] value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, JSOHelper.convertToJavaScriptArray(value)); } else if (allowPostCreate) { setProperty(attribute, JSOHelper.convertToJavaScriptArray(value)); } else { error(attribute, value.toString()); } } protected void setAttribute(String attribute, BaseClass[] value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, JSOHelper.convertToJavaScriptArray(value)); } else if (allowPostCreate) { setProperty(attribute, JSOHelper.convertToJavaScriptArray(value)); } else { error(attribute, value.toString()); } } protected void setAttribute(String attribute, BaseWidget[] value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, JSOHelper.convertToJavaScriptArray(value)); } else if (allowPostCreate) { setProperty(attribute, JSOHelper.convertToJavaScriptArray(value)); } else { error(attribute, value.toString()); } } protected void setAttribute(String attribute, float value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value); } else if (allowPostCreate) { setProperty(attribute, value); } else { error(attribute, String.valueOf(value)); } } protected void setAttribute(String attribute, double value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value); } else if (allowPostCreate) { setProperty(attribute, value); } else { error(attribute, String.valueOf(value)); } } protected void setAttribute(String attribute, Integer value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value); } else if (allowPostCreate) { if (value == null) { setNullProperty(attribute); } else { setProperty(attribute, value.intValue()); } } else { error(attribute, String.valueOf(value)); } } public native void setNullProperty(String property)/*-{ var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); widget.setProperty(property, null); }-*/; public native void setProperty(String property, String value)/*-{ var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); widget.setProperty(property, value); }-*/; public native void setProperty(String property, boolean value)/*-{ var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); widget.setProperty(property, value); }-*/; public native void setProperty(String property, int value)/*-{ var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); widget.setProperty(property, value); }-*/; public native void setProperty(String property, float value)/*-{ var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); widget.setProperty(property, value); }-*/; public native void setProperty(String property, double value)/*-{ var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); widget.setProperty(property, value); }-*/; public native void setProperty(String property, Element value)/*-{ var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); widget.setProperty(property, value); }-*/; public native void setProperty(String property, JavaScriptObject value)/*-{ var widget = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); widget.setProperty(property, value); }-*/; protected void setAttribute(String attribute, Date value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value); } else if (allowPostCreate) { if (value == null) { setNullProperty(attribute); } else { setProperty(attribute, JSOHelper.convertToJavaScriptDate(value)); } } else { error(attribute, String.valueOf(value)); } } protected void setAttribute(String attribute, JavaScriptObject value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value); } else if (allowPostCreate) { setProperty(attribute, value); } else { error(attribute, String.valueOf(value)); } } protected void setAttribute(String attribute, String[] value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, JSOHelper.convertToJavaScriptArray(value)); } else if (allowPostCreate) { setProperty(attribute, JSOHelper.convertToJavaScriptArray(value)); } else { error(attribute, String.valueOf(value)); } } protected void setAttribute(String attribute, Object[] value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, JSOHelper.convertToJavaScriptArray(value)); } else if (allowPostCreate) { setProperty(attribute, JSOHelper.convertToJavaScriptArray(value)); } else { error(attribute, String.valueOf(value)); } } protected void setAttribute(String attribute, Boolean value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value); } else if (allowPostCreate) { if (value == null) { setNullProperty(attribute); } else { setProperty(attribute, value.booleanValue()); } } else { error(attribute, String.valueOf(value)); } } protected void setAttribute(String attribute, Element value, boolean allowPostCreate) { if (!isCreated()) { JSOHelper.setAttribute(config, attribute, value); } else if (allowPostCreate) { setProperty(attribute, value); } else { error(attribute, String.valueOf(value)); } } //override default behavior of setting title for SmartGWT widgets public void setTitle(String title) { //do nothing } public String getTitle() { return ""; } public native String toString()/*-{ try { var self; if (this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) { self = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()(); } else { self = this.@com.smartgwt.client.widgets.BaseWidget::getConfig()(); } return $wnd.isc.echo(self); } catch (e) { return "ERROR: " + e.name + " -- " + e.message; } }-*/; public boolean equals(Object obj) { if (obj instanceof BaseWidget) { if (obj == this) { return true; } else { BaseWidget other = (BaseWidget) obj; if (other.id == null || id == null) return false; if (other.id.equals(id)) { return true; } } return false; } else { return false; } } public int hashCode() { return getID().hashCode(); } public NativeObject nativeObject; public LogicalStructureObject setLogicalStructure(LogicalStructureObject s) { s.scClassName = getScClassName(); return s; } public LogicalStructureObject getLogicalStructure() { BaseWidgetLogicalStructure s = new BaseWidgetLogicalStructure(); setLogicalStructure(s); return s; } public void initNativeObject() { this.nativeObject = new NativeObject(this); } }