views:

1070

answers:

3

Hello

I found this piece of code works in that i can programmatically creates a richfaces dropdown menu. But some of the code is deprecated. Can anyone tell me what to put in instead of the deprecated calls?

Thanks

     public HtmlDropDownMenu getMyMenu()
 {
  HtmlDropDownMenu menu = new HtmlDropDownMenu();
  menu.setValue( "Node Select" );

  HtmlMenuItem menuItem = new HtmlMenuItem();
  // TODO programmatically pass from getNodes into a String[] rather than an ArrayList of SelectItems
  String subOption = "myBox";   
  menuItem.setValue( subOption );

  Application app = FacesContext.getCurrentInstance().getApplication();
  javax.faces.el.MethodBinding mb = app.createMethodBinding( "#{PrismBacking.onItemClick}", new Class[] { ActionEvent.class } );
  menuItem.setActionListener( mb );

  menu.getChildren().add( menuItem );
  return( menu );
 }

 public void onItemClick( ActionEvent event )
 {
  Object obj = event.getSource();

  if( obj instanceof HtmlMenuItem )
  {
   HtmlMenuItem item = (HtmlMenuItem)obj;
   if( item != null )
   {
    lastItem = item.getValue().toString();

   }
  }
 }

deprecated code lines are:

   javax.faces.el.MethodBinding mb = app.createMethodBinding( "#{PrismBacking.onItemClick}", new Class[] { ActionEvent.class } );
  menuItem.setActionListener( mb );
+1  A: 

The replacement mechanisms are detailed in the JEE5 API (of which JSF is part):

McDowell
+1  A: 

The javadocs state it clearly:

Application.createMethodBinding

Deprecated. This has been replaced by calling getExpressionFactory() then ExpressionFactory.createMethodExpression(javax.el.ELContext, java.lang.String, java.lang.Class, java.lang.Class[]).

Here's how to use it:

MethodExpression methodExpression = 
    application.getExpressionFactory().createMethodExpression(
         FacesContext.getCurrentInstance().getELContext(), 
         "#{PrismBacking.onItemClick}", 
         null, 
         new Class[] { ActionEvent.class });
menuItem.setActionExpression(methodExpression);
Bozho
Bozho thanks for the pointer; as i'm new at java, i've no idea how to follow the instruction of the manual. can you write me an example snippet to replace the deprecated bit in the code above (which i cut and pasted in to start with). cheers
Mark Lewis
The return type of an `ActionListener` method is supposed to be `void`, so you should rather pass `null` instead of `Object.class`.
BalusC
corrected. (15)
Bozho
thanks both of you. it renders fine, but on clicking the subOption as specified in the getMyMenu method, i get a blank page and nothing in the console, even putting logging in the onItemClick method. i've read the javadocs, but i'm too new to interpret them into how to get the above to alter anything on the backing bean which i can use from within the jsp page. can you point me towards a decent howto? ta
Mark Lewis
+3  A: 

As usual, all the deprecation is indeed just described in the API docs, including details about the replacement.

To have a clear overview, here are both the pre-JSF 1.2 and post-JSF 1.2 ways to create an Action and ActionListener dynamically:

Create Action binding in JSF 1.0/1.1:

MethodBinding action = FacesContext.getCurrentInstance().getApplication()
    .createMethodBinding("#{bean.action}", new Class[0]);
uiCommandComponent.setAction(action);

Create ActionListener binding in JSF 1.0/1.1:

MethodBinding actionListener =  FacesContext.getCurrentInstance().getApplication()
    .createMethodBinding("#{bean.actionListener}", new Class[] {ActionEvent.class});
uiCommandComponent.addActionListener(actionListener);

Create Action expression in JSF 1.2 or newer:

FacesContext context = FacesContext.getCurrentInstance();
MethodExpression action = context.getApplication().getExpressionFactory()
    .createMethodExpression(context.getELContext(), "#{bean.action}", String.class, new Class[0]);
uiCommandComponent.setActionExpression(action);

Create ActionListener expression in JSF 1.2 or newer:

FacesContext context = FacesContext.getCurrentInstance();
MethodExpression actionListener = context.getApplication().getExpressionFactory()
    .createMethodExpression(context.getELContext(), "#{bean.actionListener}", null, new Class[] {ActionEvent.class});
uiCommandComponent.addActionListener(new MethodExpressionActionListener(actionListener));

To avoid lot of boilerplate code, you can just wrap it nicely in helper methods (if necessary in an helper/utility class), e.g.:

public static MethodExpression createAction(String actionExpression, Class<?> returnType) {
    FacesContext context = FacesContext.getCurrentInstance();
    return context.getApplication().getExpressionFactory()
        .createMethodExpression(context.getELContext(), actionExpression, returnType, new Class[0]);
}

public static MethodExpressionActionListener createActionListener(String actionListenerExpression) {
    FacesContext context = FacesContext.getCurrentInstance();
    return new MethodExpressionActionListener(context.getApplication().getExpressionFactory()
        .createMethodExpression(context.getELContext(), actionListenerExpression, null, new Class[] {ActionEvent.class}));
}

so that you can just use it as follows:

uiCommandComponent.setActionExpression(createAction("#{bean.action}", String.class);
uiCommandComponent.addActionListener(createActionListener("#{bean.actionListener}");
BalusC
(+1) comprehensive as usual :)
Bozho
Thanks :) (15 chars)
BalusC