11 Replies Latest reply on Oct 13, 2009 5:07 PM by judy guglielmin

    Action

    Pietro M. Newbie

      Hi everybody,


      I'm struggling with SEAM and ICEFaces... I can't figure out how to call a method by pushing a button on the view and then refresh the view to show that the action has been made.


      This is the controller I wrote:


      @Name("SperimentazioneAction")
      @Scope(ScopeType.PAGE)
      public class SperimentazioneAction {
      
           public boolean showEditMask = false;
      
           public SperimentazioneAction() {
           }
      
           public String doShowEditMask() {
                showEditMask = true;
                return(null);
           }
      
           public boolean isShowEditMask() {
                return showEditMask;
           }
      
           public void setShowEditMask(boolean showEditMask) {
                this.showEditMask = showEditMask;
           }
      }
      



      This is the view (excerpt):




           <ice:commandButton value="Aggiungi..." action="#{SperimentazioneAction.doShowEditMask}" 
                rendered="#{!SperimentazioneAction.showEditMask}" style="font-size: small;"/>
           <ice:outputText value="Show edit: #{SperimentazioneAction.showEditMask}"/>



      As a side question: should I use an action or actionlistener attribute? is it possible to call a method and pass a parameter from the view?


      I can't grasp the logic behind it.


      Thank you.



        • 1. Re: Action
          Shervin Asgari Master
          Hi. Seems to be you should read the documentation of seam a bit first before grasping all of this.

          Try to avoid using PAGE scope component. Avoid having capital letter on the first letter in your component. You need to say what goes wrong in your example. Are you always getting false as response?

          You can easily send parameters to your action. #{myComponent.action('someText')}.
          Dont return null when method is String. Try returning "success" for instance and create a rule saying "if outcome == 'success' then redirect to some other view. Put your component to CONVERSATION so that the value will be active so that on the other page you will access the component value.
          • 2. Re: Action
            Pietro M. Newbie

            Thank you for your answer.


            Hi. Seems to be you should read the documentation of seam a bit first before grasping all of this.



            I've read the first 280 pages of Seam in Action and I always keep a seam gen project as reference... please have patience, I'm studying SEAM from ten days because I have to (superior orders) make an application with this framework for work and I have a strict deadline.


            Anyway, I've made some progress.


            Controller:


            @Name("test")
            @Scope(ScopeType.CONVERSATION)
            public class Test {
                 boolean attribute;
                 
                 public Test(){
                      attribute = false;
                      System.out.println("Test created");
                 }
                 
                 public void doAttributeTrue(ActionEvent e) {
                      System.out.println("Test.setAttributeTrue (pr) = " + attribute);
                      attribute = true;
                      System.out.println("Test.setAttributeTrue (dp) = " + attribute);
                 }
                 
                 public boolean getAttribute() {
                      System.out.println("Test.getAttribute = " + attribute);
                      return attribute;
                 }
            }




            View:


            <ice:form>
                 <ice:outputText value="Valore : #{test.attribute}"/> <br />
                 <ice:commandButton value="Test" partialSubmit="true" rendered="#{!test.attribute}" actionlistener="#{test.doAttributeTrue}"/>
            </ice:form>




            Every time I load the page (I've placed the view code inside home.xhtml of a seam-gen generated project) I get this:


            00:54:47,886 INFO  [STDOUT] Test created
            00:54:47,886 INFO  [STDOUT] Test created
            00:54:47,887 INFO  [STDOUT] Test.getAttribute = false
            00:54:47,887 INFO  [STDOUT] Test.getAttribute = false
            00:54:47,887 INFO  [STDOUT] Test.getAttribute = false
            00:54:47,888 INFO  [STDOUT] Test.getAttribute = false




            Every time I click on the button I get this:



            00:57:22,940 INFO  [STDOUT] Test creato
            00:57:22,953 INFO  [STDOUT] Test creato
            00:57:22,953 INFO  [STDOUT] Test.getAttribute = false
            00:57:22,956 INFO  [STDOUT] Test.getAttribute = false
            00:57:22,959 INFO  [STDOUT] Test.getAttribute = false
            00:57:23,013 INFO  [STDOUT] Test.getAttribute = false
            00:57:23,014 INFO  [STDOUT] Test.getAttribute = false
            00:57:23,014 INFO  [STDOUT] Test.getAttribute = false
            00:57:23,015 INFO  [STDOUT] Test.getAttribute = false



            It seems that the component is created twice and the actionhandler method is never called, but I can't figure out why. Any suggestions?

            • 3. Re: Action
              Arbi Sookazian Master

              Just because you annotate your class with @Scope(ScopeType.CONVERSATION) does not mean a LRC (long-running conversation) is active during the execution of your particular use case.  You need to let the Seam container know typically via @Begin that a temporary conversation needs to be promoted to a LRC (look at the hotel booking example for tips).


              You can prove this by not adding @Begin but adding @Destroy public void destory(){...} and adding a debug brkpt in that method to see if the Seam container is actually cleaning up the temporary conversation multiple times during the JSF lifecycle (typically after the render response phase).  And remember, where there's a @Begin, there should be a @End in the same Seam component (or possibly a different one).  @End tells Seam container to demote the LRC to temp conversation for eventual destruction.


              Also understand that with JSF 1.2, the action and render attribute methods may be executed more than once during the JSF life cycle.


              You will need to focus most of your efforts first on learning JSF and then Seam conversation API and bijection (and perhaps EJB3 if you choose to use that part of J2EE and its associated set of APIs - but EJB3 is completely optional in Seam).


              Be very, very patient if you are new to this entire stack (it took me a year to learn facelets, JSF, Richfaces, EJB3, Hibernate, JPA, etc.)  Ultimately, Seam will pay dividends in the end after you have mastered all the concepts and APIs.  Right now I am working on a Struts 1.1, Spring, iBATIS, Oracle JBO, OC4J 10.1.2 AS project that is unnecessarily overly complex and vendor-dependent.  Seam is difficult at first, then pretty easy once you learn the design patterns, APIs, etc. and have some experience coding projects.


              A good way to learn the internals of Seam is to add debug brkpts in the actual Seam source code.  org.jboss.seam.persistence.ManagedPersistenceContext is a great example to learn SMPC.  The core types are here: org.jboss.seam.core.


              It is highly recommended that you carefully study the hotel booking example very thoroughly prior to starting a real-world project in earnest.  One of the main value adds of Seam is the conversation context/scope and it is demonstrated very well in that distro example project.


              Be happy you have the opportunity to work on a project with this stack, I wish I was still using it...

              • 4. Re: Action
                Pietro M. Newbie

                Thank you for your reply and your suggestions.


                Be very, very patient if you are new to this entire stack (it took me a year to learn facelets, JSF, Richfaces, EJB3, Hibernate, JPA, etc.) Ultimately, Seam will pay dividends in the end after you have mastered all the concepts and APIs.
                
                ...
                
                Seam is difficult at first, then pretty easy once you learn the design patterns, APIs, etc. and have some experience coding projects. 



                Unfortunately I don't have time to master all the technologies that SEAM encompasses. The problem is that I need to meet a strict deadline and I wish I didn't have to work with SEAM because of that (a steep-learning-curve framework is not the ideal thing when dealing in these situations, but I don't have a choice on that).


                Concerning the goal that I'm trying to accomplish (user pushes a button, an actionlistener is called and changes an attribute - i.e. false to true, the view is refreshed showing that the change has been made), do you have any idea of what I did wrong?

                • 5. Re: Action
                  xsa lefter Newbie

                  Pietro M. wrote on Oct 12, 2009 17:15:


                  Unfortunately I don't have time to master all the technologies that SEAM encompasses. The problem is that I need to meet a strict deadline and I wish I didn't have to work with SEAM because of that (a steep-learning-curve framework is not the ideal thing when dealing in these situations, but I don't have a choice on that).

                  Concerning the goal that I'm trying to accomplish (user pushes a button, an actionlistener is called and changes an attribute - i.e. false to true, the view is refreshed showing that the change has been made), do you have any idea of what I did wrong?


                  Hi pietro. Like I said at your other post, If you new in the entire stack, please learn it from seam generated code which available from seam-gen tool. You can create a database table first and use a seam generate to generate all the views, controllers, and models (entity classes). Al least, you have something for your manager, client etc to showing off ;) .


                  Of course you may need the ice faces as your jsf framework. Or you need a custom behavior from the current code. But, IMO it is more easily change it after you has been generate all your code.


                  If you found that your self uncomfortable with the generation-code tool like that, think twice because other folks at the other platform and framework (Ruby On Rails, Grails) did it extensively.


                  The Orbi suggestion and experience is the good one. Just learn from the other code before you have one.


                  May this idea help you. Sorry if you feel bad because my post. Thanks.

                  • 6. Re: Action
                    Arbi Sookazian Master

                    I recommend you write your POC app without ICEFaces at first if possible.  This will make your life easier.  You can add ICEFaces UI components later. 


                    You should be able to use a coversation-scoped component (using @Begin) and redirect to the same xhtml/JSF page via pages.xml after form submission.  Then the getter method will pickup the new value for the boolean variable.  I'm pretty sure a partial page reRender/refresh is not required when you redirect to same page but not 100% sure.



                    should I use an action or actionlistener attribute?

                    I don't recall the difference b/n the two but I have always used action.



                    is it possible to call a method and pass a parameter from the view?

                    Yes, that's possible due to JBoss EL.


                    If you still are having problems getting this simple app done, email me @ asookazian@gmail.com and I'll see if I can help you out in more detail...

                    • 7. Re: Action
                      Arbi Sookazian Master

                      Try this out:


                      @Name("sperimentazioneAction")
                      @Scope(ScopeType.CONVERSATION)
                      public class SperimentazioneAction {
                       
                              @Logger
                              private Log log;
                      
                           private boolean showEditMask = false;
                      
                              @Begin(join=true)
                           public void submit() {
                                showEditMask = true;
                           }
                      
                           public boolean getShowEditMask() {
                                return showEditMask;
                           }
                      
                           public void setShowEditMask(boolean showEditMask) {
                                this.showEditMask = showEditMask;
                           }
                      
                              @Destroy
                              @End
                              public void destroy(){
                                      log.info("sperimentazioneAction is being destroyed by Seam container.");
                              }
                      }



                      JSF:


                      <h:commandButton value="Aggiungi..." action="#{sperimentazioneAction.submit}"/>
                       <h:outputText value="Show edit: #{sperimentazioneAction.showEditMask}"/>



                      pages.xml:


                      <page view-id="/foo.xhtml">
                               <description>foo page</description>
                               <!-- <begin-conversation join="true"/> -->
                               <navigation from-action="#{sperimentazioneAction.submit}">
                                   <redirect view-id="/foo.xhtml"/>
                              </navigation>
                          </page>



                      I have not tested this solution yet.  Also, typically you will not use @End on the destroy method in your backing bean.  In your case, the @End annotation is not really required (the LRC will timeout if it becomes a background conversation or it will timeout with the HttpSession that it lives in).


                      Also note the commented line in pages.xml:


                      <begin-conversation join="true"/>



                      If you uncomment this line, the LRC will start prior to or maybe after the page rendering IIRC (definitely before the form submission and you can check this out by opening another tab and navigating to http://localhost:8080/foo/debug.seam if debug mode is enabled and you will see the active LRCs).


                      Always use join="true" or you will run into problems b/c you can only have one active LRC per session in Seam apps.


                      HTH.

                      • 8. Re: Action
                        Arbi Sookazian Master

                        Also, if your action method (in this case submit()) returns void, then JSF/Seam will redirect the user back to the same JSF page.  So you may not really need the pages.xml fragment that I posted.

                        • 10. Re: Action
                          Pietro M. Newbie

                          Thank you really much. Tomorrow I'll try your ideas.


                          In the meantime I succeeded in my goal by using an Action that returns a string (in my case I return Success). I don't understand why but if I use an actionlistener method instead of an action method, then the actionlistener isn't called.


                          Tomorrow I'll try with a conversation, as you suggest in your solution.
                          Thanks again to you and to all the people who dropped an answer.

                          • 11. Re: Action
                            judy guglielmin Novice

                            Seam in Action is a great resource.  There is sample code that you can also access (open18ice has examples of what you are looking for, although they might be a bit advanced if you are struggling with the basics of Seam).  Also available is seam-comp-showcase, which has simpler examples of how to use Seam with ICEfaces.  You can download this example from http://www.icefaces.org/main/downloads/detail.iface.  Code snippets and examples are also available on the ICEfaces forum