14 Replies Latest reply on Mar 22, 2013 8:31 AM by edewit

    cordova-ui and gui built via programatically or ui.xml templates

    milesifrr

      Hi everybody,

       

      I have just managed to have the cordova-quickstart demo working: the ui, the remote calls and the rest calls work fine. After experimenting somewhat with it, I have some question about how the user interface is built and managed.

       

      In the gwt.xml module I see

          <inherits name="org.jboss.errai.common.ErraiCommon"/>

          <inherits name="org.jboss.errai.bus.ErraiBus"/>

          <inherits name="org.jboss.errai.ioc.Container"/>

          <inherits name="org.jboss.errai.enterprise.CDI"/>

          <inherits name="org.jboss.errai.ui.Cordova"/>

          <inherits name="org.jboss.errai.enterprise.Jaxrs"/>

       

      and in the source code I have:

      @EntryPoint

      @Templated("#template")

      public class App extends Composite {

       

           private void addLabel() {

                Label label = new Label("Let's see if I see it!");

                label.setHeight("60px");

                label.setWidth("300px");

                RootPanel rootPanel = RootPanel.get();

                rootPanel.add(label);

           }

       

           @AfterInitialization

           public void createUI() {

                RootPanel rootPanel = RootPanel.get();

                rootPanel.add(this);

           }

      ....

      }

       

      Here are some questions:

      1. it seems that the templating mechanism works even if I do not have <inherits name="org.jboss.errai.ui.UI" />. It is the <inherits name="org.jboss.errai.ui.Cordova"/> that does it?
      2. I commented all the code of the createUI() method and I still have a fully functional UI. It looks like that code is not necessary, is it?
      3. Because I need to build my UI from ui.xml files or from code, I deleted the @Templated("#template") annotation and in the createUI() method I left only the row of code "addLabel();". I found out that in the browser I could only see the label, as expected, while in the Android emulator I could see nothing at all (in addLabel() I even tried RootPanel rootPanel = RootPanel.get("rootPanel"), where rootPanel is a div in the index.html page, with the same results both in the browser and in the emulator). When I restored the @Templated("#template") annotation, I found out that in the browser I could see both the label and the template ui, while in the Android emulator I could see only the template ui. So I am wondering how I can install a user interface via code or ui.xml templates.
      4. do you know if there is a tool like the chrome inspection tool to inspect the UI in the android browser?

       

      To sum things up, it looks like the @Templated annotations completely controls the process that sets up the UI and there is a discrepancy between the behaviour in the browser and the android emulator. How is it possible to build the ui in the "classic" ways with cordova-ui ?

       

      thanks in advance to anybody helping me to understand how things work

       

      ciao Francesco

        • 1. Re: cordova-ui and gui built via programatically or ui.xml templates
          edewit

          Hi Francesco,

           

          Great that your trying out errai-cordova, now to answer your questions:

           

          1. It would have been nicer if the module was explicit inherited here your right I'll update this.

          2. Also right about this because this demo makes use of errai-ui this createUI method is not used it is something left over when the demo was converted from using ui-binder to errai-ui. If you want an example of how to do this in a more 'classic' way you can take a look at the kitchensink demo. The errai-cordova demo is based on this and you can easly compare the two.

          3. I would recomend you to use errai-ui to build something that is supposed to work on both mobile and web. With it you have much easier control over the layout and how it looks. If you want to debug the html have a look at weinre also have a look at this video to find out more errai-ui. Because it's based on templates you can test your ui on a device and see how it works really quickly. If your not convinced and still want to use ui-binder have a look at how the kitchensink demo is set it up.

          4. Try weinre

           

          erria-cordova will give you cdi events for phone releated things like battery-low warnings and you can inject the camera as you can see in the KitchenSinkClient.java

           

          Hope this helps,

               Erik Jan

          • 2. Re: cordova-ui and gui built via programatically or ui.xml templates
            milesifrr

            Hi Erik,

             

            your answer was really helpful, but I have some follow-up questions.

             

            Nothing has been decided yet, but we were thinking to use mgwt, that have a set of widget that adapts to different contexts (phone, tablet and, to a lesser extent, the browser) without doing nearly anything and at the same time have a very platform like feeling (especially with ios). That's why we were trying to use ui.xml templates.

            After your answer I have two more question

            1. we obviously would like to have all that comes with errai-cordova and you described in your answer, but that means we cannot use the ui.xml templates, because the templating mechanism of cordova-ui and that using ui.xml files are mutually exclusive? so if we want to go the ui.xml way, we have to renounce to the errai-cordova functionalities?
            2. do you think that creating a very platform-like user interface for the different environments would be a heavy task? have you got any suggestions on how to to do that?

             

            Finally thanks for the weinre link, it is just what we need.

             

            thanks again

             

            ciao Francesco

            • 3. Re: cordova-ui and gui built via programatically or ui.xml templates
              edewit

              Hi Francesco,

               

              I know mGWT I've used it in the past. There is no reason why you cannot use mGWT together with errai, that way you get your native looking widgets together with all the good stuff of errai. The reason we didn't build something like mGWT is that when mimicing the native interface people tent not to like it. In robotics they call this the Uncanny Valley  It says that when you have a robot that tries to be human but isn't quite right, it revolts the observer. The effect occurs when you get very close to real human behavior, but not quite there - the revulsion response is subconscious. The same holds true for interfaces I would advice you to make something that doesn't try to look and behave native. Rather use responsive ui and have something that looks nice and consistent if you don't need to use the camera or other native integration there is no need to use anything like cordova.

               

              Hope this helps with making up your mind,

               

                   Cheers,

                        Erik Jan

              • 4. Re: cordova-ui and gui built via programatically or ui.xml templates
                milesifrr

                Hi Erik

                 

                I do agree with you, but the problem is that out client wants a native looking app.

                So let's see if I understood correctly what you said.

                 

                I have two alternatives:

                1. using errai without cordova-ui (because cordova-ui doesn't let me build the ui using ui.xml templates or programatically) together with mgwt and something like gwtphonegap to access the phonegap js library
                2. using errai with the cordova-ui module and having a nice app that does not look native

                 

                I have already tried to use errai+mgwt+gwtphonegap, but I couldn't have my app started on the android emulator, Basically, I used the KitchenSink archetype to generate my project then added gwtphonegap and mgwt.

                Do you think this combination can work? If it can, I will try to find out what goes wrong... To tell the truth, I didn't invest so much time trying to find out the problem... Maybe it's something trivial.

                 

                thanks again

                 

                ciao Francesco

                • 5. Re: cordova-ui and gui built via programatically or ui.xml templates
                  mdhirsch30345

                  Erik,

                   

                  Thanks for the pointer to weire.  It looks really useful.

                   

                  In case anyone is interested, I found that the link provided is old and no longer has any downloads.  Instead, go to http://people.apache.org/~pmuellr/weinre/docs/latest/ to find out about weinre.  Weinre lets you debug a webpage remotely.  So you can have it running on your phone and debug it on your development machine.

                   

                  Thanks!

                   

                  Michael

                  • 6. Re: cordova-ui and gui built via programatically or ui.xml templates
                    edewit

                    Hi Francesco,

                     

                    You almost got it   here are your alternatives:

                     

                    1. errai-cordova with mGWT you don't need gwtphonegap because that is what errai-cordova is for. It wrappes cordova native functionality in CDI injectable way. If you take a look at the cordova-kichensink example (KitchenSinkClient) you will see that it uses the camera by injecting it.

                     

                    2. use errai-ui together with errai-cordova and some nice responsive layout to get a site that works well on desktop but still uses native functionality when depoyed on mobile using cordova.

                     

                    But if you really want something that looks native I guess you really only have one option. What I would recomend you to do is first try and prototype the UI and get a feel for how fast it is. Because of gwt it can be really optimised for the device, but still it's HTML and javascript and will not feel as snappy as native widgets.

                     

                    Happy hacking ,

                         Erik  Jan

                    • 7. Re: cordova-ui and gui built via programatically or ui.xml templates
                      milesifrr

                      Hi Erik,

                       

                      thanks for your kind answer.

                      I reviewd all posts and I think I unnecessarily made things too complicated, while, probably, the only problem I ever had is stated in point 3 of the first post of this thread. To make things more understandable I created this class from the cordova-quickstart demo

                       

                      @EntryPoint

                      @Templated("#template")

                      public class App extends Composite {

                           @Inject

                           Camera camera;

                       

                           @Inject

                           @DataField

                           Button takePicture;

                       

                           @PostConstruct

                           public final void init() {

                             if(takePicture != null)

                                   takePicture.addClickHandler(new ClickHandler() {

                                   @Override

                                                              public void onClick(ClickEvent event) {

                                                                             onTakePictureClick();

                                                              }

                                   });

                           }

                       

                           @AfterInitialization

                           public void createAO() {

                                addLabel();

                                addLabel();

                                if(takePicture != null)

                                                              takePicture.setText("Take pooooocture!");

                           }

                       

                                private void addLabel() {

                                          Label label = new Label("Ola bombolon!");

                                          label.setHeight("600px");

                                          label.setWidth("600px");

                                          label.setVisible(true);

                                          System.out.println("label->" + label);

                                          RootPanel rootPanel = RootPanel.get();

                                          //                    RootPanel rootPanel = RootPanel.get("rootPanel");

                                          rootPanel.add(label);

                                }

                       

                                void onTakePictureClick() {

                                          takePicture.setText("Take pooooocture!");

                                          PictureOptions options = new PictureOptions(25);

                                          options.setDestinationType(PictureOptions.DESTINATION_TYPE_DATA_URL);

                                          options.setSourceType(PictureOptions.PICTURE_SOURCE_TYPE_CAMERA);

                       

                       

                           camera.getPicture(options, new PictureCallback() {

                             @Override

                             public void onSuccess(String data) {

                                  Window.alert("OOOOOOOOOOOOOk!!!!!!");    

                             }

                             @Override

                             public void onFailure(String error) {

                                  Window.alert("Could not take member picture: " + error);    

                             }

                          });

                      }

                       

                      and here are the inherited modules

                          <inherits name="org.jboss.errai.common.ErraiCommon"/>

                          <inherits name="org.jboss.errai.bus.ErraiBus"/>

                          <inherits name="org.jboss.errai.ioc.Container"/>

                          <inherits name="org.jboss.errai.enterprise.CDI"/>

                          <inherits name="org.jboss.errai.ui.Cordova"/>

                          <inherits name="org.jboss.errai.enterprise.Jaxrs"/>


                       

                      Everything works perfectly, bus, camera, ui, everyting, but in my laptop browser I see the label, I add via code, at the end of my page, while in my android virtual device I do not see anything.

                      As I understand it, if I comment the @Templated("#template") annotation, switching off errai's templating mechanism, I should be able to build my ui in the usual ways (ui.xml templates or code), but what I get is that I can see the two labels in my laptop browser, while in the android virtual device I do not see anything at all.

                       

                      That's why I cannot understand if I am doing things right or not. Because of this unexpected behaviour (to me at least)... In my laptop browser I get a result and in the android virtual device a different one.

                      I also tried to debug the emulator web page using weinre, but while it works perfectly if I load the page in my laptop browser it does not work with the android virtual device: I only see the connection url in the debug client for an instant, but it disappears before I can do anything...

                       

                      I do not understand if I am doing something wrong or if there is a problem with my emulator (I tried different configurations...). Maybe I should try a real device.

                       

                      thanks again in advance for yout help

                       

                      ciao Francesco

                      • 8. Re: cordova-ui and gui built via programatically or ui.xml templates
                        edewit

                        Hi Fancesco,

                         

                        I would recomend using an acual device for debugging I've also had strange render problems on the simulator. Other then that I can't really explain why you would see different result on the simulator, because cordova is just a native application that uses an integrated browser.

                         

                        One thing that springs in mind is, that because cordova is running the html from a remote location it needs full url to connect to the server instead of relative ones. Have you configured the generated Config.java with the right remote url? If so have you started your jboss with the -b 0.0.0.0 so that it doesn't refuse connections from external locations?

                         

                        Hope that helps,

                             Erik Jan

                        • 9. Re: cordova-ui and gui built via programatically or ui.xml templates
                          milesifrr

                          Hi Erik,

                          Have you configured the generated Config.java with the right remote url?

                          yes. Here it is http://172.16.1.52:8080/tpl/

                          If so have you started your jboss with the -b 0.0.0.0 so that it doesn't refuse connections from external locations?

                          yes

                           

                          The fact that you also had problems with the emulator redering suggets me to try with an actual device.

                          To tell the truth, I have just done that, but I got a communication with server error... Well I wasn't particurlarly lucky lately... When I connect from the browser (using my ip address, not localhost) and when I use the emulator, the communication is fine. And I am sure the device is connected to the network because I can see it in weinre.

                           

                          I will try with another device and see what happens.

                           

                          For the moment, thanks again

                           

                          ciao Francesco

                          • 10. Re: cordova-ui and gui built via programatically or ui.xml templates
                            milesifrr

                            Hi everybody,

                             

                            I used an actual device and inspected the page dom with weinre and I verified that the labels aren't there... I don't know why.

                             

                            Maybe I should wait for later releases...

                             

                            thanks to everybody

                             

                            ciao Francesco

                            • 11. Re: cordova-ui and gui built via programatically or ui.xml templates
                              edewit

                              Hi Francesco,

                               

                              When you run it on the device what do you get in logcat? Can you attach some logs? You could try the server url also inside the browser on the device and see if it's a cordova problem.

                               

                              Cheers,

                                   Erik Jan

                              • 12. Re: cordova-ui and gui built via programatically or ui.xml templates
                                milesifrr

                                Hi Erik,

                                 

                                I made different attempts, on different devices. You can find my project, generated from the cordova-quickstart archetype and reduced to a minimum, and the android logs attached.

                                 

                                All the work is done in the EntryPoint class App.java that I show here for reference:

                                 

                                @EntryPoint

                                @Templated("#template")

                                public class App extends Composite {

                                 

                                 

                                          private Logger log = Logger.getLogger(getClass().getName());

                                 

                                 

                                          @Inject

                                          Camera camera;

                                 

                                 

                                          @Inject

                                          @DataField

                                          Image image;

                                 

                                 

                                          @Inject

                                          @DataField

                                          Button takePicture;

                                 

                                 

                                          @PostConstruct

                                          public final void init() {

                                                    if(takePicture != null)

                                                              takePicture.addClickHandler(new ClickHandler() {

                                                                        @Override

                                                                        public void onClick(ClickEvent event) {

                                                                                  onTakePictureClick();

                                                                        }

                                                              });

                                          }

                                 

                                 

                                          @AfterInitialization

                                          public void createAO() {

                                                    log.info("-----------createUI-------------");

                                                    addLabel();

                                                    addLabel();

                                                    addLabel();

                                                    if(takePicture != null)

                                                              takePicture.setText("TYou should really take a pictuuuuuuuuure!!");

                                          }

                                 

                                 

                                          private void addLabel() {

                                                    Label label = new Label("You should see me everywhere.........");

                                                    label.setHeight("600px");

                                                    label.setWidth("150px");

                                                    label.setVisible(true);

                                                    RootPanel rootPanel = RootPanel.get();

                                                    //                    RootPanel rootPanel = RootPanel.get("rootPanel");

                                                    rootPanel.add(label);

                                          }

                                 

                                 

                                          void onTakePictureClick() {

                                                    takePicture.setText("Take pooooocture!");

                                                    PictureOptions options = new PictureOptions(25);

                                                    options.setDestinationType(PictureOptions.DESTINATION_TYPE_DATA_URL);

                                                    options.setSourceType(PictureOptions.PICTURE_SOURCE_TYPE_CAMERA);

                                 

                                 

                                                    camera.getPicture(options, new PictureCallback() {

                                 

                                 

                                                              @Override

                                                              public void onSuccess(String data) {

                                                            image.setUrl(UriUtils.fromSafeConstant("data:image/jpeg;base64," + data));

                                                                        Window.alert("OOOOOOOOOOOOOk!!!!!!");

                                                              }

                                 

                                 

                                                              @Override

                                                              public void onFailure(String error) {

                                                                        Window.alert("Could not take member picture: " + error);

                                                              }

                                                    });

                                          }

                                 

                                 

                                }

                                 

                                 

                                These are the results:

                                1. phonegap works fine: I can take a picture and show it in an image tag.
                                2. The simulator and the actual device (I tried with a tablet with android 4.0.3 and an htc phone with 2.3) have the same behaviour: it seems that the @AfterInitialization code is never executed. I don't see the labels added to the root panel and the button label is never set to "You should really take a pictuuuuuuuuure!!"
                                3. The browser, both of my laptop and of the android devices, shows the labels and the button label is set to "You should really take a pictuuuuuuuuure!!"
                                4. If I comment the @Templated("#template") tag, in the emulator and actual devices I get a blank page, while in the browser I get the labels

                                 

                                Should I put the code to build the gui in a different place or the fact that the @AfterInitialization code never gets called in the devices is a bug? 

                                 

                                thanks again for your help

                                 

                                ciao Francesco

                                • 13. Re: cordova-ui and gui built via programatically or ui.xml templates
                                  edewit

                                  Hi Francesco,

                                   

                                  I see you found a bug the @AfterInitialization is not getting called on the device, your code will work when you call all of it in the @PostConstruct I've filed a bug ERRAI-359 and will work on a solution.

                                   

                                  Cheers,

                                       Erik Jan

                                  • 14. Re: cordova-ui and gui built via programatically or ui.xml templates
                                    edewit

                                    Done Francesco,

                                     

                                    If you build your example with

                                     

                                    mvn clean install -U

                                     

                                    You should be able to see your labels also on a mobile device turned out to be a bug in gwtphonegap where errai cordova is dependend on.

                                     

                                    Cheers,

                                         Erik Jan