8 Replies Latest reply on Oct 14, 2008 3:52 AM by Seg Fault

    dropDownMenu: problem on migration from 3.1.6 to 3.2.2

    Seg Fault Newbie

      Hi!

      I'm using Richfaces 3.1.6 and JSF 1.2_09b2.
      Now I need to migrate to 3.2.2 for using new functionalities and fixes of table scrolling.
      However I have migration problems on the rich:dropDownMenu component.

      Looking at the migration guide, I found only wrong behaviours concerning the use of JSF 1.2_08.

      http://www.jboss.org/file-access/default/members/jbossrichfaces/freezone/docs/migrationguide/en/html_single/index.html#menuJSF

      However I use version 1.2_09b2. So those shouldn't affect me (I hope).

      What I have to do with dropDownMenu is to show the list of supported languages and let the user choose the preferred language.
      The list is implemented as a dropDownMenu showing the flag as icon (in the example below I've put a text label in place of the flag image) and the extended language name as label. When the user choose the language, it appears on top of the dropDownMenu and disappears from the languages proposed in the dropDownMenu.

      For instance:

      it
      |--------------------|
      | de | Deutsch |
      | en | English |
      | es | Espaniol |
      | fr | Francaise |
      |--------------------|
      


      The current user choice is for language "Italian". If the user select language "English", the above becomes:
      en
      |--------------------|
      | de | Deutsch |
      | es | Espaniol |
      | fr | Francaise |
      | it | Italian |
      |--------------------|
      


      Unfortunately with RIchfaces 3.2.2 I get this:

      Before selection:
      it
      |-----------------------|
      | de | deDeutsch |
      | en | enEnglish |
      | es | esEspaniol |
      | fr | frFrancaise |
      |-----------------------|
      


      After selection (of "English"):
      en
      |-----------------------|
      | de | deDeutsch |
      | en | enEnglish |
      | es | esEspaniol |
      | fr | frFrancaise |
      |-----------------------|
      


      Here below is my code:

      JSPX page:
      <?xml version="1.0" encoding="UTF-8"?>
      
      <jsp:root version="2.1"
       xmlns:jsp="http://java.sun.com/JSP/Page"
       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:rich="http://richfaces.org/rich">
      
       <jsp:directive.page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"/>
       <jsp:output omit-xml-declaration="no"
       doctype-root-element="html"
       doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
       doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>
      
       <f:view>
       <html xmlns="http://www.w3.org/1999/xhtml">
       <head>
       <title>RichFaces *DROP-DOWN-MENU* component test</title>
       </head>
       <body>
       <h1>RichFaces *DROP-DOWN-MENU* component test</h1>
      
       <h:form id="menu-test">
      
       <rich:dropDownMenu id="myMenu-cforEach" submitMode="server">
       <f:facet name="label">
       <h:panelGrid cellpadding="0" cellspacing="0" columns="1" style="vertical-align:middle">
       <h:outputText value="#{dropDownMenuBean.myChoice}"/>
       </h:panelGrid>
       </f:facet>
       <c:forEach items="#{dropDownMenuBean.pairList}" var="item">
       <rich:menuItem value="#{item.first}" action="#{dropDownMenuBean.choiceChangeAction}">
       <f:setPropertyActionListener target="#{dropDownMenuBean.currentChoice}" value="#{item.first}"/>
       <f:facet name="icon">
       <h:outputText value="#{item.first}"/>
       </f:facet>
       <h:outputText value="#{item.second}"/>
       </rich:menuItem>
       </c:forEach>
       </rich:dropDownMenu>
       </h:form>
       </body>
       </html>
       </f:view>
      </jsp:root>
      


      Class used in the page bean (see below):
      import java.io.Serializable;
      
      /**
       * Store a pair of objects, possibly of different types.
       */
      public class Pair<V1,V2> implements Serializable, Comparable<Pair<V1,V2>>
      {
       private V1 v1; /** The first element. */
       private V2 v2; /** The second element. */
      
       /** A constructor. */
       public Pair(V1 v1, V2 v2)
       {
       this.v1 = v1;
       this.v2 = v2;
       }
      
       /**
       * Returns the first element.
       */
       public V1 getFirst()
       {
       return this.v1;
       }
      
       /**
       * Returns the second element.
       */
       public V2 getSecond()
       {
       return this.v2;
       }
      
       @Override
       public String toString()
       {
       return "<" + this.v1 + ", " + this.v2 + ">";
       }
      
       public int compareTo(Pair<V1,V2> o)
       {
       return 0;
       }
      
       @Override
       @SuppressWarnings("unchecked")
       public boolean equals(Object o)
       {
       if ( o instanceof Pair )
       {
       Pair<V1,V2> p = null;
      
       try
       {
       p = (Pair<V1,V2>) o;
       }
       catch (ClassCastException cce)
       {
       return false;
       }
      
       return this.getFirst().equals( p.getFirst() ) && this.getSecond().equals( p.getSecond() );
       }
      
       return super.equals(o);
       }
      }
      


      Page bean:
      import java.util.ArrayList;
      import java.util.List;
      import java.util.logging.Level;
      import java.util.logging.Logger;
      
      import javax.faces.context.ExternalContext;
      import javax.faces.context.FacesContext;
      
      /**
       * Page-Bean for testing the {@code rich:dropDownMenu} tag.
       */
      public class TestRichDropDownMenuBean
      {
       private static final transient Logger Log = Logger.getLogger( TestRichDropDownMenuBean.class.getName() );
       private static final String MYCHOICE_KEY = "mychoice";
      
       /** PROPERTY: myChoice. */
       public String getMyChoice()
       {
       ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
       if (ctx.getSessionMap().containsKey(MYCHOICE_KEY))
       {
       Log.info("TestRichDropDownMenuBean::getMyChoice>> Found previously stored choice: " + (String) ctx.getSessionMap().get(MYCHOICE_KEY));
      
       return (String) ctx.getSessionMap().get(MYCHOICE_KEY);
       }
      
       Log.info("TestRichDropDownMenuBean::getMyChoice>> No previously stored choice found.");
      
       return "it";
       }
      
       /** PROPERTY: pairList. */
       private List<Pair<String,String>> pairList = null;
       protected void setPairList(List<Pair<String,String>> value) { this.pairList = value; }
       public List<Pair<String,String>> getPairList()
       {
       if (this.pairList == null)
       {
       this.pairList = new ArrayList<Pair<String,String>>();
       this.pairList.add( new Pair<String,String>( "de", "Deutsch") );
       this.pairList.add( new Pair<String,String>( "en", "English" ) );
       this.pairList.add( new Pair<String,String>( "es", "Espaniol") );
       this.pairList.add( new Pair<String,String>( "fr", "Francaise" ) );
       this.pairList.add( new Pair<String,String>( "it", "Italiano") );
      
       // Retrieve the current choice
       String curChoice = null;
       if (this.getCurrentChoice() == null || this.getCurrentChoice().length() == 0)
       {
       // Actually, in the first case
       curChoice = this.getMyChoice();
       }
       else
       {
       curChoice = this.getCurrentChoice();
       }
      
       // Remove current choice from the choice list
       for (int i = 0; i < this.pairList.size(); i++)
       {
       if ( this.pairList.get(i).getFirst().equals( curChoice ) )
       {
       this.pairList.remove(i);
       break;
       }
       }
       }
      
       Log.info( "TestRichDropDownMenuBean::getPairList>> returning list of pairs" );
      
       return this.pairList;
       }
      
       /** PROPERTY: curChoice. */
       private String curChoice;
       public String getCurrentChoice() { return this.curChoice; }
       public void setCurrentChoice(String value) { this.curChoice = value; }
      
       public String choiceChangeAction()
       {
       Log.info("TestRichDropDownMenuBean::choiceChangeAction>> Changing menu item: " + this.getCurrentChoice());
      
       Log.info("TestRichDropDownMenuBean::choiceChangeAction>> Old choice: " + this.getMyChoice());
      
       ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext();
       ctx.getSessionMap().put(MYCHOICE_KEY, this.getCurrentChoice());
      
       Log.info("TestRichDropDownMenuBean::choiceChangeAction>> New choice: " + this.getCurrentChoice());
      
       return "ok";
       }
      }
      


      faces-config.xml fragment:
      ...
       <managed-bean>
       <managed-bean-name>dropDownMenuBean</managed-bean-name>
       <managed-bean-class>it.unipmn.di.dcs.sharegrid.web.portal.view.test.TestRichDropDownMenuBean</managed-bean-class>
       <managed-bean-scope>request</managed-bean-scope>
       </managed-bean>
      ...
      


      Please, can anyone help me?

      Thanks in advance!

      -- Marco