Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    How to register listeners with nested components using componentXML (possible bug)?

    Hi,

    I've some component inside a ComponentXML like this:
    Code:
    ...
    <DynamicForm ID="ViewsForm">
    	<fields>
    		<SelectItem ID="ViewsFormSelectItem" width="240">
    			<title><fmt:message key='tabBar_Views' /></title>
    			<name>ViewsFormSelectItem2</name>
    			<icons>
    				<PickerIcon ID="EditViewButton" width="16" height="16">
    					    <src>[SKIN]/actions/edit.png</src>
    					    <name>EditViewButton2</name>
    				</PickerIcon>
    ...
    Now, I'd like to add a click event to the SaveViewButton to call custom java code. Since there are currently no other options, I try it programmatically.

    Since the PickerIcon is not a Canvas, Canvas.getById() does not work here.

    Instead, I try to obtain the DynamicForm by Canvas.getById(), then its DynamicForm fields and from there the PickerIcon like this:
    Code:
    final DynamicForm dynamicForm = (DynamicForm) Canvas.getById("ViewsForm");
    FormItem[] fields = dynamicForm.getFields();
    final FormItem formItemField = dynamicForm.getField("ViewsFormSelectItem2");
    FormItemIcon editIcon = formItemField.getIcon("EditViewButton2");
    editIcon.addFormItemClickHandler(new FormItemClickHandler() {	
    	@Override
    	public void onFormItemClick(FormItemIconClickEvent event) {
    		SC.say(formItemField+" button clicked.");
    	}
    })
    SC.say("HandlerCount: "+ editIcon.getHandlerCount(new Type<FormItemClickHandler>()));
    In prodcution, the editIcon.getHandlerCount() pops up saying "HandlerCount: 0".
    In addition, the onFormItemClick is never invoked when clicking on the icon (no popup).
    Maybe this is a similar problem as described here: http://forums.smartclient.com/showthread.php?t=26343
    except that this time, the widgeds could not be replaced by their global counterparts and the global ones are somehow shadowed by the "anonymous" ones?

    By inspecting the FormItemIcon/PickerIcon using Firefox, I see this (which weakens the assumption above):
    Code:
    <span id="isc_3A" handlenativeevents="false" $9a="EditViewButton2" $89="ViewsFormSelectItem" tabindex="4040" style="margin-left:0px;-moz-user-focus:normal;cursor:pointer" role="button"></span>
    When trying to debug it in dev mode, the following uncatched exception (logged via)
    Code:
    GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {		
    	@Override
    	public void onUncaughtException(Throwable e) {
    		GWT.log("Uncaught exception",e);
    	}
    });
    is raised while invoking dynamicForm.getFields() or dynamicForm.getField("ViewsFormSelectItem2"):
    Code:
    com.google.gwt.dev.shell.HostedModeException: Something other than a boolean was returned from JSNI method '@com.smartgwt.client.widgets.form.fields.FormItem::isCreated()': JS value of type undefined, expected boolean
        at com.google.gwt.dev.shell.JsValueGlue.get(JsValueGlue.java:100)
        at com.google.gwt.dev.shell.ModuleSpace.invokeNativeBoolean(ModuleSpace.java:196)
        at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeBoolean(JavaScriptHost.java:35)
        at com.smartgwt.client.widgets.form.fields.FormItem.isCreated(FormItem.java)
        at com.smartgwt.client.widgets.form.fields.FormItem.setAttribute(FormItem.java:4123)
        at com.smartgwt.client.widgets.form.fields.FormItem.setName(FormItem.java:4397)
        at com.smartgwt.client.widgets.form.fields.FormItem.<init>(FormItem.java:109)
        at com.smartgwt.client.widgets.form.fields.TextItem.<init>(TextItem.java:113)
        at com.smartgwt.client.widgets.form.fields.FormItemFactory.getFormItem(FormItemFactory.java:13)
        at com.smartgwt.client.widgets.form.DynamicForm.convertToFormItemArray(DynamicForm.java:3274)
        at com.smartgwt.client.widgets.form.DynamicForm.getFields(DynamicForm.java:3260)
        at com.myCompany.myOnLoadClass$2.execute(MyOnLoadClass.java:77)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
        at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
        at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
        at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:338)
        at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:219)
        at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
        at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:571)
        at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:279)
        at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
        at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
        at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:242)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
        at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
        at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
        at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:293)
        at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:547)
        at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:364)
        at java.lang.Thread.run(Thread.java:722)
    So, how to register a listener with the FormItemIcon?

    FF 20.0.1 & Version 26.0.1410.64 m
    v8.3p_2013-04-28/PowerEdition Deployment (built 2013-04-28)

    Thanks,
    fatzopilot
    Last edited by fatzopilot; 4 May 2013, 11:17.

    #2
    Hi Fatzopilot
    What you're doing here:
    - getting the DynamicForm,
    - using "getItem" to get the item,
    - and using "getIcon" to get the icon in Java scope,
    - then adding the handler to it,
    should all work as far as we can tell. We've attempted to replicate your results, and found with similar Java code in a simple standalone test, clicking on the icon does indeed show the prompt.

    There may be some subtle difference between your usage and our test case that accounts for this. To determine what this might be, could you put together a standalone test case for us that we can run as written on our end, and show us the source for each part?

    In other words:
    - a bootstrap file which simply loads your component XML and the application.
    - Simplify the component XML down to just this Form definition (and show the complete set of XML to us, whether its embedded in the bootstrap or loaded as a separate file)
    - an entry point class which does only the steps described here (attempts to add the click handler to the icon) and if necessary draws the form.

    This should give us everything we need to see exactly the behavior you're getting.

    Thanks
    Isomorphic Software

    Comment


      #3
      Hi,

      I'm sorry, it don't know what was different the first time but it works now in production/compiled mode...
      However, I still get the Exception in dev mode (so it does not work there) and the handler count stays 0.

      Here is the code:
      Portal.ui.xml
      Code:
      <isomorphicXML xmlns:fmt="WEB-INF/">
      	<DynamicForm ID="ViewsForm">
      		<fields>
      		    <SelectItem ID="ViewsFormSelectItem" width="240">
      		        <title><fmt:message key='tabBar_Views' /></title>
      		        <name>ViewsFormSelectItem2</name>
      	    		<icons>
      	    		    <PickerIcon ID="EditViewButton" width="16" height="16">
      					    <src>[SKIN]/actions/edit.png</src>
      					    <name>EditViewButton2</name>
      					</PickerIcon>
      				 </icons>
      			</SelectItem>
      		</fields>
      	</DynamicForm>
      
      	<TabSet ID="PortalTabSet" autoDraw="true" width="100%" height="100%" tabBarAlign="left">
      		<tabs>
      			<Tab title="Tab0" canClose="true">
      				<ID>Tab0</ID>
      				<name>Tab0</name>
      			</Tab>
      		</tabs>
      		<tabBarControls>
      			<value>tabScroller</value>
      			<value>tabPicker</value>
      			<value>ViewsForm</value>
      		</tabBarControls>
      	</TabSet>
      	<DataView ID="PortalDataView" width="100%" height="100%"
      		overflow="hidden" autoDraw="true">
      		<members>
      			<Canvas ref="PortalTabSet" />
      		</members>
      		<modulesDir>modules/</modulesDir>
      	</DataView>
      </isomorphicXML>
      Code:
      package com.aCompany.client;
      
      import com.google.gwt.core.client.EntryPoint;
      import com.google.gwt.core.client.GWT;
      import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
      import com.google.gwt.event.shared.GwtEvent.Type;
      import com.smartgwt.client.rpc.LoadScreenCallback;
      import com.smartgwt.client.rpc.RPCManager;
      import com.smartgwt.client.util.SC;
      import com.smartgwt.client.widgets.Canvas;
      import com.smartgwt.client.widgets.form.DynamicForm;
      import com.smartgwt.client.widgets.form.fields.FormItem;
      import com.smartgwt.client.widgets.form.fields.FormItemIcon;
      import com.smartgwt.client.widgets.form.fields.events.FormItemClickHandler;
      import com.smartgwt.client.widgets.form.fields.events.FormItemIconClickEvent;
      
      /**
       * Entry point classes define <code>onModuleLoad()</code>.
       */
      public class GWTModule implements EntryPoint {
          /**
           * This is the entry point method.
           */
      	@Override
      	public void onModuleLoad() {
      		
      		GWT.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
      			
      			@Override
      			public void onUncaughtException(Throwable e) {
      				GWT.log("Uncaught exception",e);
      			}
      		});
      		
      		String[] globalIds = new String[]{
      				"ViewsForm"
      				};
      		
      		RPCManager.loadScreen("Portal", new LoadScreenCallback() {
      			
      			@Override
      			public void execute() {
      				final DynamicForm dynamicForm = (DynamicForm) Canvas.getById("ViewsForm");
      				final FormItem formItemField = dynamicForm.getField("ViewsFormSelectItem2");
      				FormItemIcon editIcon = formItemField.getIcon("EditViewButton2");
      				editIcon.addFormItemClickHandler(new FormItemClickHandler() {	
      					@Override
      					public void onFormItemClick(FormItemIconClickEvent event) {
      						SC.say(formItemField+" button clicked.");
      					}
      				});
      				SC.say("editIcon.getHandlerCount(new Type<FormItemClickHandler>());"+ editIcon.getHandlerCount(new Type<FormItemClickHandler>()));
      			}
      		}, globalIds);
      	}
      }
      Regards,
      fatzopilot

      Comment


        #4
        Thanks for the response. We'll look into these.
        On the positive side, it sounds like you've actually got a working solution as far as end users are concerned at least since the behavior is being added correctly in compiled mode (though obviously we'll try to get to the bottom of these mysterious problems with the handler count / dev mode behavior).

        Regards
        Isomorphic Software

        Comment


          #5
          Code:
          FormItemIcon editIcon = formItemField.getIcon("EditViewButton2");
          editIcon.addFormItemClickHandler(new FormItemClickHandler() {	
          	@Override
          	public void onFormItemClick(FormItemIconClickEvent event) {
          		SC.say(formItemField+" button clicked.");
          	}
          })
          Using a debugger step into the addFormItemClickHandler(..) method --> doAddHandler --> com.google.gwt.event.shared.HandlerManager-->addHandler(type, handler)

          Looking at the code path it seems strange that you'd even get into a situation that getHandlerCount returns 0 after the above code is executed. Also step through the getHandlerCount() method and examine the variables. This should hopefully help you narrow down the issue.

          Sanjiv

          Comment


            #6
            Hi Sanjiv,

            my problem here is that I don't get thus far...
            The exception mentioned above is raised at
            Code:
            dynamicForm.getField("ViewsFormSelectItem2");
            or, alternatively at
            Code:
            dynamicForm.getFields();
            Java 7.0.21
            Google Web Toolkit 2.5.1 (svn revision releases/2.5@11546)
            I get it in FF, Chrome, and IE dev mode on Windows 8 (64-bit).
            As mentioned, in compiled mode it works OK, except that even here the handler count is 0;

            I've create a small project to replicate the issue: https://www.dropbox.com/s/4kgb3v3cbammqu2/SGWTIntegrationTest.rar

            I left the (this time) smartGWTEE (demo) libs included for convenience.
            First install grails 2.2.2. :http://dist.springframework.org.s3.amazonaws.com/release/GRAILS/grails-2.2.2.zip
            Set the GWT_HOME variable to your GTW directory
            Change into the project dir (.../SGWTIntegrationTest/)
            run
            > grails war
            in the project directory. After compilation finished, run
            > grails run-gwt-client
            Run
            > grails run-app
            in the same shell.

            Call http://localhost:8080/SGWTIntegrationTest/sgwt?gwt.codesvr=127.0.0.1:9997
            in the browser.
            The same happens in debug mode if the project is imported into GGTS (Grails Eclipse Flavor).

            Regards,
            fatzopilot

            Comment

            Working...
            X