4 Replies Latest reply on May 11, 2011 11:21 AM by kapuzo

    rich:panelMenu loses layout/theme and gets dublicated

    kapuzo

      Hi,

      I trying to build a rich:panelMenu, but it wont work.

      At first a small sumary of my project:

      I am building a little onlinestore, nothing complicated but only with JSF 2.0 it lokks like a boring HTML/PHP or wahtever Website. So I decided to use Richfaces, because of the additional components and the ajax support.

      A page of my application contains a template and this template is made of some other template-pages. So that I have got a default-remplate which includes a header, menu, linklist and a footer. The content is a ui:insert so that every page can define its content. In the menu-template I want the panelMenu to be.

       

      default.xhtml (main-template)

       

      <?xml version="1.0" encoding="UTF-8"?>

      <!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:f="http://java.sun.com/jsf/core"

          xmlns:h="http://java.sun.com/jsf/html"

          xmlns:ui="http://java.sun.com/jsf/facelets"

          xmlns:rich="http://richfaces.org/rich"

          xmlns:a4j="http://richfaces.org/a4j">

      <h:head>

          <title><ui:insert name="title">

                  <h:outputText value="#{labels.title_app}" />

              </ui:insert>

          </title>

          <link href="#{request.contextPath}/css/layout.css" rel="stylesheet"

              type="text/css" />

      </h:head>

      <h:body>

          <f:view>

              <h:panelGroup id="page" layout="block" styleClass="page">

                  <h:panelGroup id="header" layout="block" styleClass="header">

                      <ui:include src="header.xhtml" />

                  </h:panelGroup>

                  <h:panelGroup id="contentBackground" layout="block"

                      styleClass="contentBackground">

                      <h:panelGroup id="menu" layout="block" styleClass="menu">

                          <ui:include src="menu.xhtml" />

                      </h:panelGroup>

                      <h:panelGroup id="shopPathContainer" layout="block"

                          styleClass="shopPathContainer">

                          <h:outputText value="#{labels.current_position}: " />&rsaquo; 

                      <ui:insert name="currentPosition" />

                      </h:panelGroup>

                      <h:panelGroup id="content" layout="block" styleClass="content">

                          <ui:insert name="content" />

                      </h:panelGroup>

                      <h:panelGroup id="links" layout="block" styleClass="links">

                          <ui:include src="links.xhtml" />

                      </h:panelGroup>

                      <h:panelGroup id="bottomSeparator" layout="block"

                          styleClass="bottomSeparator">

                          <h:panelGroup id="bottomSeparatorLeft" layout="block"

                              styleClass="bottomSeparatorLeft" />

                          <h:panelGroup id="bottomSeparatorContent" layout="block"

                              styleClass="bottomSeparatorContent" />

                      </h:panelGroup>

                  </h:panelGroup>

                  <h:panelGroup id="footer" layout="block" styleClass="footer">

                      <ui:include src="footer.xhtml" />

                  </h:panelGroup>

              </h:panelGroup>

          </f:view>

      </h:body>

      </html>

       

      menu.xhtml

       

      <?xml version="1.0" encoding="UTF-8"?>

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

      <ui:composition xmlns="http://www.w3.org/1999/xhtml"

          xmlns:c="http://java.sun.com/jsp/jstl/core"

          xmlns:f="http://java.sun.com/jsf/core"

          xmlns:h="http://java.sun.com/jsf/html"

          xmlns:ui="http://java.sun.com/jsf/facelets"

          xmlns:rich="http://richfaces.org/rich"

          xmlns:a4j="http://richfaces.org/a4j">

          <h:form id="menuForm">

              <rich:panelMenu binding="#{menuBean.panelMenu}" activeItem="#{menuBean.activeItem}"

                  id="menu" style="width:158px"

                  itemMode="ajax" groupMode="ajax"

                  groupExpandedLeftIcon="triangleDown"

                  groupCollapsedLeftIcon="triangle"

                  topGroupExpandedLeftIcon="triangleDown"

                  topGroupCollapsedLeftIcon="triangle"

                  itemLeftIcon="grid">

                  <rich:panelMenuGroup id="ID1" label="Group 1" actionListener="#{menuBean.changeActiveMenuItem}" action="#{...}">

                      <rich:panelMenuItem id="ID2" label="Item 1.1" actionListener="#{menuBean.changeActiveMenuItem}" action="#{...}" />

                      <rich:panelMenuItem id="ID3" label="Item 1.2" actionListener="#{menuBean.changeActiveMenuItem}" action="#{...}" />

                      <rich:panelMenuItem id="ID4" label="Item 1.3" actionListener="#{menuBean.changeActiveMenuItem}" action="#{...}" />

                  </rich:panelMenuGroup>

                  <rich:panelMenuGroup id="ID5" label="Group 2" actionListener="#{menuBean.changeActiveMenuItem}" action="#{...}">

                      <rich:panelMenuItem id="ID6" label="Item 1.1" actionListener="#{menuBean.changeActiveMenuItem}" action="#{...}" />

                      <rich:panelMenuItem id="ID7" label="Item 1.2" actionListener="#{menuBean.changeActiveMenuItem}" action="#{...}" />

                      <rich:panelMenuItem id="ID8" label="Item 1.3" actionListener="#{menuBean.changeActiveMenuItem}" action="#{...}" />

                  </rich:panelMenuGroup>

              </rich:panelMenu>

          </h:form>

      </ui:composition>

       

      For exmaple my index.xhtml, which is the mainpage of the application looks like:

       

      <?xml version="1.0" encoding="UTF-8"?>

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

      <ui:composition template="../templates/default.xhtml"

          xmlns="http://www.w3.org/1999/xhtml"

          xmlns:f="http://java.sun.com/jsf/core"

          xmlns:h="http://java.sun.com/jsf/html"

          xmlns:ui="http://java.sun.com/jsf/facelets"

          xmlns:rich="http://richfaces.org/rich"

          xmlns:a4j="http://richfaces.org/a4j">

          <ui:define name="currentPosition">

              <h:outputText value="#{labels.title_main}" />

          </ui:define>

          <ui:define name="content">

              <h1>

                  <h:outputText value="#{labels.welcome}" />

              </h1>

          </ui:define>

      </ui:composition>

       

      login.xhtml

       

      <?xml version="1.0" encoding="UTF-8"?>

      <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

      <ui:composition template="../templates/default.xhtml"

          xmlns="http://www.w3.org/1999/xhtml"

          xmlns:f="http://java.sun.com/jsf/core"

          xmlns:h="http://java.sun.com/jsf/html"

          xmlns:ui="http://java.sun.com/jsf/facelets">

          <ui:define name="currentPosition">

              <h:outputText value="#{labels.title_login}" />

          </ui:define>

          <ui:define name="content">

              <h1>

                  <h:outputText value="#{labels.title_login}" />

              </h1>

              <h:panelGroup id="centerBox" layout="block" styleClass="centerBox">

                  <h:panelGrid id="loginGrid" columns="2">

                      <h:outputLabel value="#{labels.username}:" for="username"

                          styleClass="gridLeft" />

                      <h:panelGroup id="usernameGroup" layout="block">

                          <h:message for="username" showDetail="true" showSummary="false"

                              styleClass="message small" />

                          <h:inputText id="username" binding="#{loginBean.usernameField}"

                              value="#{loginBean.username}" size="15" required="true"

                              requiredMessage="#{notifications.required}" />

                      </h:panelGroup>

       

                      <h:outputLabel value="#{labels.password}:" for="password"

                          styleClass="gridLeft" />

                      <h:panelGroup id="passwordGroup" layout="block">

                          <h:message for="password" showDetail="true" showSummary="false"

                              styleClass="message small" />

                          <h:inputSecret id="password" binding="#{loginBean.passwordField}"

                              value="#{loginBean.password}" size="15" required="true"

                              requiredMessage="#{notifications.required}" />

                      </h:panelGroup>

                  </h:panelGrid>

              </h:panelGroup>

          </ui:define>

      </ui:composition>

       

      The menu uses the ManagedBean MenuBean. I abbreviated the class a bit:

       

      @ManagedBean

      @SessionScoped

      public class MenuBean implements Serializable {

       

          private static final long serialVersionUID = 6047892824472925159L;

          private static Logger log = Logger.getLogger(MenuBean.class.toString());

       

          @EJB

          private ProductService productService;

       

          private List<Category> rootCategories = new ArrayList<Category>();

          private List<AbstractPanelMenuItem> menuItems = new ArrayList<AbstractPanelMenuItem>();

       

          private UIPanelMenu panelMenu;

          private String activeItem;

       

          @PostConstruct

          public void init() {

                //Getting the Categories from the EJB and build the UIPanelMenu

                //Its not used in the current version

          }

       

          private void createMenu(Category c, UIComponent parent) {

                //The MenuBuilding-Method, not used yet

          }

       

           // Getter and Setter for the other variables......

       

          public UIPanelMenu getPanelMenu() {

                // retuns on the first call null, but I did not see any difference if I create a new Object or the context does it.

              return panelMenu;

          }

       

          public void setPanelMenu(UIPanelMenu panelMenu) {

              this.panelMenu = panelMenu;

          }

       

          public void setActiveItem(String activeItem) {

              this.activeItem = activeItem;

          }

       

          public String getActiveItem() {

              return activeItem;

          }

       

          public void changeActiveMenuItem(ActionEvent event) {

              this.updateActiveItem(event.getComponent());

          }

       

          private void updateActiveItem(UIComponent comp) {

              if (comp != null) {

                  String tmp = this.getComponentID(comp.getClientId());

                  if (comp instanceof UIPanelMenuGroup && tmp.equals(activeItem)) {

                      activeItem = null;

                  } else {

                      activeItem = tmp;

                  }

              } else {

                  activeItem = null;

              }

          }

       

          private String getComponentID(String id) {

              return id.substring(id.indexOf(":") + 1, id.length());

          }

       

          public String navigate() {

              log.info("Navigating to : " + activeItem);

              return NavigationUtil.INDEX;

          }

      }

       

      Finally the web.xml. That coulb be the troublemaker, because of a lot testing and changing.

       

      <?xml version="1.0" encoding="UTF-8"?>

      <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

          version="3.0">

          <display-name>onlinestore</display-name>

          <servlet>

              <servlet-name>Faces Servlet</servlet-name>

              <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>

              <load-on-startup>1</load-on-startup>

          </servlet>

          <servlet-mapping>

              <servlet-name>Faces Servlet</servlet-name>

              <url-pattern>*.jsf</url-pattern>

          </servlet-mapping>

          <welcome-file-list>

              <welcome-file>index.html</welcome-file>

          </welcome-file-list>

          <context-param>

              <param-name>javax.faces.DEFAULT_SUFFIX</param-name>

              <param-value>.xhtml</param-value>

          </context-param>

          <context-param>

              <param-name>javax.faces.PROJECT_STAGE</param-name>

              <param-value>Development</param-value>

          </context-param>

          <context-param>

              <param-name>javax.faces.STATE_SAVING_METHOD</param-name>

              <param-value>server</param-value>

          </context-param>

          <context-param>

              <param-name>org.richfaces.SKIN</param-name>

              <param-value>DEFAULT</param-value>

          </context-param>

      </web-app>

      These are the components that with which I got some trouble.

       

      I am using as developing environment:

      Eclipse EE 3.6 with JBossTools

      Glassfish 3.1 Full

      Mojarra JSF Impl which comes with Glassfish, not sure what version it is

      Richfaces 4.0.0 Final, with additional libs:

           richfaces-components-api-4.0.0.Final

           richfaces-components-ui-4.0.0.Final

           richfaces-core-api-4.0.0.Final

           richfaces-core-impl-4.0.0.Final

           cssparser-0.9.5

           guava-r09

           guava-r09-gwt

           xml-apis

           xml-apis-ext

       

      Now to the problems:

       

      I am trying to build a rich:panelMenu in a ManagedBean, which is SessionScoped. But as soon as I bind that rich:panelMenu from my JSF-page to a UIPanelMenu in my BackingBean the menu loses its theming. Or, to be more precise, it still has the style-tags but it does not show those styles.

      Probably it is easier for you to understand, so I got two images of that behaviour.

       

      ExpectedWhat happened
      http://imageshack.us/m/96/8803/groupsok.pnghttp://imageshack.us/m/833/7810/groupsfail.png

       

      On the first pageload the menu has its theming, but after a page-reload or a menuAction the theming is gone and the items are no langer "clickable". If I add a rich:panelMenu to that page and dont bind it, the menu is shown as I would expect it and works fine.

       

      That is my first problem.

       

      Now to the second one:

      It also caused by the binding. Without binding there is no problem.

      If I change the page from index.jsf to login.jsf, the menu is added twice and I got a java.lang.IllegalStateException that says:

      Component-ID menuForm:ID1 is already on that View. (Sorry for that but the console output is not in english on my pc)

      at com.sun.faces.util.Util.checkIdUniqueness(Util.java:821)

          at com.sun.faces.util.Util.checkIdUniqueness(Util.java:805)

          at com.sun.faces.util.Util.checkIdUniqueness(Util.java:805)

          at com.sun.faces.util.Util.checkIdUniqueness(Util.java:805)

          at com.sun.faces.util.Util.checkIdUniqueness(Util.java:805)

          at com.sun.faces.util.Util.checkIdUniqueness(Util.java:805)

          at com.sun.faces.util.Util.checkIdUniqueness(Util.java:805)

          at com.sun.faces.application.view.StateManagementStrategyImpl.saveView(StateManagementStrategyImpl.java:140)

          at com.sun.faces.application.StateManagerImpl.saveView(StateManagerImpl.java:133)

          at com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:225)

          at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:418)

          at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)

          at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)

          at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)

          at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)

          at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)

          at javax.faces.webapp.FacesServlet.service(FacesServlet.java:410)

          at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1534)

          at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)

          at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)

          at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)

          at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)

          at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)

          at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)

          at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)

          at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:326)

          at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:227)

          at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:170)

          at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822)

          at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719)

          at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013)

          at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)

          at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)

          at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)

          at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)

          at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)

          at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)

          at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)

          at com.sun.grizzly.ContextTask.run(ContextTask.java:71)

          at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)

          at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)

          at java.lang.Thread.run(Thread.java:662)

       

       

      Puh, that was a long way to go .

      But now to my Question:

      1. Why is the rich.panelMenu losing the theming or why is the theme no longer shown?

      2. Why is the context trying to add the menu twice? What can I do to prevent that to happen?

       

      Would be very nice if someone knows a solution for my problems, because I did not get any ideas after searching for three days to handle these problems.

        • 1. rich:panelMenu loses layout/theme and gets dublicated
          iabughosh

          what RF version do you have ?

          • 2. rich:panelMenu loses layout/theme and gets dublicated
            kapuzo

            Oh sorry, that information was a slighly hidden in my text.

             

            I am using as developing environment:

            Eclipse EE 3.6 with JBossTools

            Glassfish 3.1 Full

            Mojarra JSF Impl which comes with Glassfish, not sure what version it is

            Richfaces 4.0.0 Final, with additional libs:

                 richfaces-components-api-4.0.0.Final

                 richfaces-components-ui-4.0.0.Final

                 richfaces-core-api-4.0.0.Final

                 richfaces-core-impl-4.0.0.Final

                 cssparser-0.9.5

                 guava-r09

                 guava-r09-gwt

                 xml-apis

                 xml-apis-ext

            • 3. rich:panelMenu loses layout/theme and gets dublicated
              iabughosh

              about your theme please add sac-1.3.jar to your app, and the skin parameter is no longer in upper case ex:

              <context-param>

                <param-name>org.richfaces.skin</param-name>

                <param-value>blueSky</param-value>

              </context-param>

               

              regards

              1 of 1 people found this helpful
              • 4. Re: rich:panelMenu loses layout/theme and gets dublicated
                kapuzo

                Thanks for your fast answers, my theming/skinning problem is solved because ich put the pages index into the template folder. If they are next to each other the menu works and it keeps its theme

                 

                The jar that you mentioned made no "visible" differnce in the application.

                About the context-param, I had several problems with that, but obviously the problems were not caused by the skin name. I changed it to lower case.

                 

                However problem number one is solved .

                 

                But there is still the problem with the dublicated menuItems if I change the page from index.jsf to login.jsf or something else. Probably I screwed up the jsf templating.

                 

                Thanks a lot, because of you I had some new ideas for fixing the problem .

                 

                EDIT:

                 

                I finally found my mistake. It was a mix out of wrong instanciation of the UIComponents and a wrong linking between my pages.

                I found by chance an entry where Ilya Shaikovsky solved a similar problem. The link to that entry is: http://community.jboss.org/message/592091#592091

                The Theme got also lost when I was not using the navigations rules in faces-config.

                 

                The answer for the question why I got the dublicated Exception was maybe to easy to see it.

                The generated panelMenu was bound to the ManagedBean and on changing the page, the menu was still bound. But in the templates i had a hard coded menu and that was probably trying to add the same items to the existing menu. Thats my answer for that problem.