3 Replies Latest reply on Jun 1, 2010 1:33 AM by Igor Grinfeld

    How to add listener attribute to component?

    Igor Grinfeld Newbie

      I have new component, I've developed lately. It is day of week buttons with ability to select several days. Days selected are stored in value property as bit mask. Now, I try to add attribute named daySelectedListener. This attribute should call bean's action method when one of the days is clicked. There are some examples in richFaces source code, for example currentDateChangeListener of rich:calendar, but there is no explanations in richFaces CDK tutorial how to do it, besides list of the conventional names  for methods and classes. I've tried to define daySelectedListener element. as it done in currentDateChangeListener attribute, but it doesn't works. The component is generated without errors, but when I try to add this attribute to component in test page I get following exception : "An error occurred at line: 25 in the jsp file: /testWeekDaysButtons.jsp $ cannot be resolved".

      Debugging shows me that I have this lines in TLD for these two attributes( currentDateChangeListener and daySelectedListener):

      :

      <attribute>
           <description>MethodExpression representing an action listener method that will be notified
                 after date selection</description>
           <name>currentDateChangeListener</name>
           <deferred-method>
           <method-signature>void currentDateChangeListener(org.richfaces.event.CurrentDateChangeEvent)</method-signature>
           </deferred-method>
      </attribute>
       
      <attribute>
           <description>MethodBinding representing an action listener method that will be notified after day clicked</description>
           <name>daySelectedListener</name>
           <deferred-method>
                <method-signature>void daySelectedListener(${prop.methodargs})</method-signature>
           </deferred-method>
      </attribute>
      

       

      As you can see, method signature element for my attribute has wrong parameters definition, but I don't know what the reason. Is some body know what I do in wrong way, and how to define listener attribute correctly?

       

      My way to define listener attribute:

       

      1. Add attribute element to component XML :

       

      <property>
           <name>daySelectedListener</name>
           <classname>javax.el.MethodExpression</classname>
           <description>MethodBinding representing an action listener method that will be notified after 
                day clicked</description>
      </property>
      

       

      2. Add listener element to component XML:

       

      <listener>
           <name>daySelectedListener</name>
           <listenerclass>com.sintecmedia.components.event.DaySelectedListener</listenerclass>
           <componentclass>com.sintecmedia.components.component.UIWeekdaysButtons</componentclass>
           <eventclass>com.sintecmedia.components.event.DaySelectedEvent</eventclass>
           <taghandler generate="true">
                <classname>com.sintecmedia.components.taglib.DaySelectedListenerTagHandler</classname>
           </taghandler>
      </listener>
      
        • 1. Re: How to add listener attribute to component?
          Igor Grinfeld Newbie

          I'm sorry but I'm commit a post, before I've finished it. I continue:

           

          3. Add method invocation in broadcast() method of component:

           

          //Invoke listener
          MethodExpression methodExpression = getDaySelectedListener();
          if( methodExpression != null ) {
          FacesContext facesContext = getFacesContext();
             methodExpression.invoke( 
                      facesContext.getELContext(), new Object[] { event } );
          }
          
          

           

          4. Ad listener methods in component's class:

           

          public DaySelectedListener[] getDaySelectedListeners() {
               return (DaySelectedListener[]) getFacesListeners(
                    DaySelectedListener.class);
          }
                    
          public void addDaySelectedListener( DaySelectedListener listener ) {
               addFacesListener(listener);
          }
               
          public void removeDaySelectedListener( DaySelectedListener listener ) {
                 removeFacesListener(listener);
          }
                    
          public abstract MethodExpression getDaySelectedListener();
          public abstract void setDaySelectedListener( MethodExpression scrollerListener );
          

           

          5. Add method to test's managed bean:

           

          public class WeekDaysButtonsTestBean {
               private int dayFlags = 3;
               public int getDays() { return dayFlags; }     
               public void setDays( int dayFlags ) { this.dayFlags = dayFlags;     }
               
               protected void updateDay( int index, Boolean val ) {
                    if( val ) {
                         setDays( getDays() & ~UIWeekDaysButtons.DAY_MASKS[ index ] );
                    } else {
                         setDays( getDays() | UIWeekDaysButtons.DAY_MASKS[ index ] );
                    }
               }
          
               public void ddl( DaySelectedEvent event ) {
                    int index = event.getDayIndex();
                    if( ( getDays() & UIWeekDaysButtons.DAY_MASKS[ index ] ) > 0 ) {
                         setDays( getDays() & ~UIWeekDaysButtons.DAY_MASKS[ index ] );
                    } else {
                         setDays( getDays() | UIWeekDaysButtons.DAY_MASKS[ index ] );
                    }          
               }
          

           

          6. Add attribute to test page:

           

          <my:weekDaysButtons value="#{testWeekDaysBean.days}" daySelectedListener="#{testWeekDays.ddl}" />
          

           

          Full component source is attached. What wrong with it?

          • 2. Re: How to add listener attribute to component?
            Nick Belaevski Master

            You have two typos in your code:

             

            - &listeners; , but not &listener;

            - com.sintecmedia.components.component.UIWeekDaysButtons and not com.sintecmedia.components.component.UIWeekdaysButtons

             

            One more thing you've missed is explicit declaration for TagHandler generation in the component section.

            • 3. Re: How to add listener attribute to component?
              Igor Grinfeld Newbie

              Thank you, Nick. I've already found first mistake, but I couldn't catch the second, although I've checked this file several times.