JavaServer Faces and Dynamic component insertion queries
Hello frnds
Am a newbie to JavaServer Faces, I want to use JSF for creating a toolbar in my application. Now my question is can I have a class that creates components dynamically and also have the components actionlistener method in it?
Well I want to have a plugin kind of a toolbar, that talks to an engine and dynamically creates the components and its actionlisteners (probably as an external jar file) Am not sure whether am allowed to have my components(dynamically created ones) and my actionlisteners in a single class file.
So code snippet would look somethin like this
ALL IN A SINGLE JAR FILE
com.components
import necessary packages
public class somename
{
HtmlOutputText text = new HtmlOutputText();
text.setValue("GO");
text.setRendered(true);
panelgrid.getChildren().add(text);
HtmlCommandButton button = new HtmlCommandButton();
button.addActionListener(listen);
panelgrid.getChildren().add(button);
public void listen(ActionEvent e)
{
HtmlOutputText tt = new HtmlOutputText();
text.setValue("hi");
panelgrid.getChildren().add(tt);
}
}
The above code doesnot have a logic. I just want to know whether its possible. If not please show me some other way to deal with it. Any help would be greatly appreciated.
Thanks a lot!
# 1
If I understand you correctly, this is very doable. The key is to declare your component in your JSP/facelet empty except for the binding attribute. The binding attribute indicates a backing bean property that is of the same type as your component. Then build the component and its children in the backing bean and return it.
It wouldn't surprise me to learn that BalusC has an example of this in his JSF documentation. Try googling for it.
# 2
Thanks a lot for your reply. I am working on it !
# 3
Sorry one more question, is it possible to have the components and its action listeners alone in a separate jar file and include it in the web application? Probably say my jsp file creates the components to be displayed during the runtime from the class in the jar file.
Because this would help me to enhance the features of my application in future without having to go through complex panelgrid tags, and also am using rich faces to enable drag and drop support for the components so that makes the situation even more complex if i have to add new components to the existing application. Hope am clear n any suggestions would be of great help to me.
Thanks in advance
# 4
I don't see why not, many organizations distribute a JSF component library as a separate jar file.
# 5
Yea thats true but, a lot of times (atleast as of what i have seen) the organizations develop their own components but what am looking for is to reuse existing components, have my own listeners for them and pack them into a separate jar file and include it during runtime.
So in this case Iam not sure how to add Action Listeners. Any ideas?
Thanks again for your replies so far and I'd be glad if anyone could help me in the right direction.
# 6
If you are going to configure the action listeners as standard managed beans and include an actionListener or action attribute on the component definitions in your page then everything should work without an issue. You just need to make sure the jar file is in the classpath for the WAR. Unless you are looking for something more automagical...
# 7
Here is something that seems not to work, could any one please tell me why is it ?
{
//parent Grid takes all components to the engine
HtmlPanelGrid pg = new HtmlPanelGrid();
//initialise all components to be added to grid
HtmlOutputText outtext1 = new HtmlOutputText();
HtmlOutputText outtext2 = new HtmlOutputText();
HtmlCommandButton button = new HtmlCommandButton();
//set the values for components
outtext1.setValue("New External Comp");
outtext2.setValue("New External Comp2");
button.setValue("GO");
outtext1.setId("Lay1");
outtext2.setId("Lay2");
button.addActionListener(listen);
//add actionlisteners for the components
//button.addActionListener(listen);
pg.getChildren().add(outtext1);
pg.getChildren().add(outtext2);
//panelGrid.getChildren().add(outtext1);
//panelGrid.getChildren().add(outtext2);
this.panelGrid = pg;
return panelGrid;
}
public void listen(ActionEvent e)
{
//Listen to the events
}
I want to have actionlistener and add that actionlistener to a button as well in the same java file. I would be glad if someone could talk me through how this could be done. Also please let me know how to write faces-config.xml file if i have to actionlisteners in a separate managed bean class?
# 8
Which JSF version are you using and how have you created the 'listen' MethodExpression reference? I don't see that in your code.
# 9
Iam using myfaces 1.1.5 but Iam not sure what is MethodExpression Reference! sorry for my ignorance am a newbie to jsf but I'd be glad to learn if you could give me some directions.
# 10
Has anyone tried to use addActionListener or setActionListener methods for command button or command link ? i want to add action listeners programmatically....is there any good tutorials for adding components and action listeners programmatically? Your reply would be of great help as am doing my final year project in JavaServer Faces. Thanks a lot in advance
# 11
The JSF 1.1 way, using the deprecated createMethodBinding:HtmlCommandButton button = new HtmlCommandButton();
MethodBinding actionListener =
FacesContext.getCurrentInstance().getApplication().createMethodBinding("#{myBean.actionListener}", new Class[] {ActionEvent.class});
button.setActionListener(actionListener);
button.setValue("invoke actionListener");
The JSF 1.2 way, using new EL factory:// Prepare
FacesContext facesContext = FacesContext.getCurrentInstance();
ExpressionFactory expressionFactory = facesContext.getApplication().getExpressionFactory();
ELContext elContext = facesContext.getELContext();
// Create actionListener button.
HtmlCommandButton button = new HtmlCommandButton();
MethodExpression actionListener =
expressionFactory.createMethodExpression(elContext, "#{myBean.actionListener}", null, new Class[] {ActionEvent.class});
button.addActionListener(new MethodExpressionActionListener(actionListener));
button.setValue("invoke actionListener");
Which generates:<h:commandButton value="invoke actionListener" actionListener="#{myBean.actionListener}" />
Which invokes:public void actionListener(ActionEvent event) {
// Implement.
}
# 12
Thanks a lot BalusC, that was exactly what I was looking for. Could you please tell me how createMethodBinding method works? or could you please direct me to some tutorial on it...because I looked up in API and docs for createMethodBinding but I dont get a clear picture of it... Thanks in advance.
# 13
I am sorry, but the API was descriptive enough.
UICommand#setActionListener() expects a MethodBinding.
http://java.sun.com/javaee/javaserverfaces/1.1/docs/api/javax/faces/component/UICommand.html#setActionListener(javax.faces.el.MethodBinding)
You can create a MethodBinding using Application#createMethodBinding().
http://java.sun.com/javaee/javaserverfaces/1.1/docs/api/javax/faces/el/MethodBinding.html
http://java.sun.com/javaee/javaserverfaces/1.1/docs/api/javax/faces/application/Application.html#createMethodBinding(java.lang.String,%20java.lang.Class[])
That's like 1 + 1 = 2 for me.
# 14
Fair enough. Anyways thanks again.
Cheers