3 Replies Latest reply on Mar 17, 2009 8:35 PM by nbelaevski

    tabPanel: session scoped bean generates too many valueChange

      If my valueChange listener for a tabPanel is a session scoped bean, each time I revisit the page that contains the tabPanel a new valueChangeListener is added.

      This causes the processValueChange method to be call for each valueChangeListener. I would expect that the processValueChange listener in my backing bean to be called only once.

      My application requires that his bean be session scoped so changing the scope is not a viable option.

      Thanks in advance!

      The following code illustrates this:




      
      import javax.faces.event.AbortProcessingException;
      import javax.faces.event.ValueChangeEvent;
      import javax.faces.event.ValueChangeListener;
      
      import org.richfaces.component.html.HtmlTabPanel;
      
      
      
      
      //SESSION SCOPED BEAN
      
      public class PanelTestBean implements ValueChangeListener {
      
       private HtmlTabPanel tabs = new HtmlTabPanel();
      
       public HtmlTabPanel getTabs() {
       return tabs;
       }
      
       public void setTabs(HtmlTabPanel tabs) {
       this.tabs = tabs;
       System.out.println("Number of listeners: " + tabs.getValueChangeListeners().length);
       }
      
       public void processValueChange(ValueChangeEvent event) throws AbortProcessingException {
       System.out.println("\nFire event:\nOld tab:" + event.getOldValue());
       System.out.println("New tab:" + event.getNewValue());
       }
      
       public String getListenerCount() {
       return "Number of listeners: " + getTabs().getValueChangeListeners().length;
       }
      
      }
      
      
      
      
      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      
      <html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:rich="http://richfaces.org/rich"
       xmlns:a4j="http://richfaces.org/a4j">
      
      
      <ui:composition template="layout/layout.xhtml">
       <ui:define name="title">Panel Test</ui:define>
       <ui:define name="content">
       <rich:tabPanel switchType="ajax" binding="#{panelTestBean.tabs}"
       valueChangeListener="#{panelTestBean.processValueChange}"
       id="panelTab">
       <rich:tab label="Panel 1" id="P1">
       <h:outputText value="#{panelTestBean.listenerCount}" />
       </rich:tab>
       <rich:tab id="P2" label="Panel 2">
       <h:outputText value="#{panelTestBean.listenerCount}" />
       </rich:tab>
       <rich:tab id="P3" label="Panel 3">
       <h:outputText value="#{panelTestBean.listenerCount}" />
       </rich:tab>
       </rich:tabPanel>
       </ui:define>
      </ui:composition>
      </html>
      


        • 1. Re: tabPanel: session scoped bean generates too many valueCh
          nbelaevski

          Hello,

          Components should not be wired to session-scoped beans. Remove binding and try.

          • 2. Re: tabPanel: session scoped bean generates too many valueCh

            Thank you --

            I removed the binding and it is no longer generating multiple listeners.

            Regarding components and session-scoped beans. Is this a general rule or does it only apply to this component or components that have listeners?

            I got around my issue by finding the component from my bean using the 'findComponentFor' method. Needed a reference to the panel to programatically change the active tab. This works. See any problems with this?

            Thanks again....

            • 3. Re: tabPanel: session scoped bean generates too many valueCh
              nbelaevski

               

              Regarding components and session-scoped beans. Is this a general rule or does it only apply to this component or components that have listeners?
              Yes, it's a general rule for all components.

              I got around my issue by finding the component from my bean using the 'findComponentFor' method. Needed a reference to the panel to programatically change the active tab. This works. See any problems with this?

              No problems.

              BTW, you can inject session-scoped bean into request-scoped one and so leave "binding" attribute.