Adding a button at run time
I know that you can add components at run time (I've done it with a tree for instance) but how do you link a run time added component with an action handler?
For example, when you use the designer, you just double click on a button to get an action handler built that automatically gets called when the application is deployed and that button is clicked. Well, when you add a button at run time, you have no way of doing this.
Just how do you link a dynamic button to an action handler then?
Thanks
[524 byte] By [
darrinps] at [2007-11-26 6:13:34]

# 1
FacesContext context = FacesContext.getCurrentInstance();
MethodBinding mb = (MethodBinding) context.getApplication().createMethodBinding("#{Page1.lark_action}", null);
newOne.setAction(mb);
For example:
1. drag a button, a messageGroup, and a gridPanel onto designer
2. add a SessionBean property called counter of type int with an initial value of 0.
3. double click the button and add the following source:
//Create unique button id's
int count = getSessionBean1().getCounter();
String testBtn = "testBtn" + count;
//Set parent
UIComponent parent = gridPanel1;
//define buttons
Button newOne = new Button();
newOne.setId(testBtn);
newOne.setText("This is the text Value");
//create the methodbind
FacesContext context = FacesContext.getCurrentInstance();
MethodBinding mb = (MethodBinding) context.getApplication().createMethodBinding("#{Page1.lark_action}", null);
newOne.setAction(mb);
//add to grid
boolean childAdded = parent.getChildren().add(newOne);
getSessionBean1().setCounter(++count);
return null;
4. after button1_action add the following method:
public String lark_action() {
info("Lark action has been called");
return null;
}
5. deploy/run
Click the button and get a new button in the gridpanel. Click the new button and its action method gets called putting a message in the messageGroup.
Hope it helps,
Lark
# 2
Thanks larkula2,I have one more question here. If binding the button to an action, is there a way to identify which button is clicked? I am afraid that I have to use actionlistener to do it. Really appreciate your help
field at 2007-7-6 13:50:09 >

# 3
Hi,
A slight change as below to your above code should do the trick. Basically instead of creating MethodBinding that points an action, you need to create a MethodBinder that points to a actionListener
MethodBinding mb = (MethodBinding) context.getApplication().createMethodBinding("#{Page1.lark_actionListener}", null);
newOne.setActionListener(mb);
To your Page bean, add a method called, lark_actionListener that takes Action Event and you can easily get hold of the component that caused of the event.
public void lark_actionListener(ActionEvent ae) {
UIComponent eventSrc = ae.getComponent();
}
Hope this helps.
-Jayashri
Creator team
# 4
Hi,
I generate a table at runtime and also bind it to a dataprovider at runtime and display the records in a table. It works find and I have no problem with that.
I am trying to add a new column with the button in them, i generate the buttons at runtime. Even this works fine. Along with the data in the table i have the last column with all buttons.
I am having problem binding the method to the button at runtime. My code is something like this...
-
for (int i = 0; i <= numOfCols ; i++) {
//add the delete button as the first column
if( i == 0 ){
TableColumn column = new TableColumn();
column.setHeaderText("Delete");
Button st = new Button();
st.setText("Del");
st.setId("del");
MethodBinding mb = (MethodBinding) context.getApplication().createMethodBinding("#{Page.delete_action}", null);
st.setAction(mb);
column.getChildren().add(st);
getTableRowGroup1().getChildren().add(column);
} else{
TableColumn column = new TableColumn();
column.setHeaderText(rsm.getColumnLabel(i));
log("rsm.getColumnLabel("+i+"): "+rsm.getColumnLabel(i));
column.setNoWrap(true);
column.setSort(rsm.getColumnName(i));
ValueBinding vb = app.createValueBinding("#{currentRow.value['" + rsm.getColumnName(i) + "']}");
StaticText st = new StaticText();
st.setValueBinding("text", vb);
column.getChildren().add(st);
getTableRowGroup1().getChildren().add(column);
}
}
--
public String delete_action() {
log("Inside delete_action().");
return null;
}
The method delete_action() is not called at all.
It would be appreciated if someone could help me with this problem of mine.
Thanks,
Adi.
# 5
I noticed that you use Page in the following code. Is Page really the name of the page?
MethodBinding mb = (MethodBinding) context.getApplication().createMethodBinding("#{Page.delete_action}", null);
st.setAction(mb);
In the jsp code, what does this tag look like?
<ui:page binding="#{Page1.page1}" id="page1">
# 6
Hi Jetsons,
No, actually i changed that so that the code looks simpler because i have a lot of subdirectories. so its something like,
MethodBinding mb = (MethodBinding) context.getApplication().createMethodBinding("#{pos$generic$d2.delete_action}", null);
st.setAction(mb);
I generate this button at runtime and am trying it to bind it to a method at runtime. So i can't see it in the jsp code.
There's another button that i add in desing time for which code in the jsp is something like this,
<ui:button action="#{pos$generic$d2.updtBtn_action}" binding="#{pos$generic$d2.updtBtn}" id="updtBtn"
style="left: 575px; top: 168px; position: absolute" text="UPDATE"/>
Thanks,
Adi.
# 7
There's just one error in my code that i'd sent earlier, and that is
Button st = new Button();
st.setText("Del");
st.setId("delete");
I've tried all possible methods but still couldn't make delete_action() to be called which is
public String delete_action() {
log("delete clicked....");
return null;
}
# 8
Winston supplied the following code, which I tried and it worked. He said he would update the zip in his blog to add the button code.
// Add the fourth table Column to the table row group
rowGroup.getChildren().add(tableColumn4);
// Create the button and set its action binding as button1_action
Button button1 = new Button();
button1.setText("Select");
button1.setId("button1");
button1.setAction(getApplication().createMethodBinding("#{Page1.button1_action}", null));
tableColumn4.getChildren().add(button1);
# 9
Thanks for your reply. I tried what you told but still was not able to get the button click action. What i did was, I created a new page and dropped a basic > Table in design mode and in the java code i added the following code in the init() method...
--
TableColumn tableColumn4 = new TableColumn();
// Add the fourth table Column to the table row group
getTableRowGroup1().getChildren().add(tableColumn4);
// Create the button and set its action binding as button1_action
Button button1 = new Button();
button1.setText("Select");
button1.setId("button1");
button1.setAction(getApplication().createMethodBinding("#{Page1.button1_action} ", null));
tableColumn4.getChildren().add(button1);
--
This is method to check for the button action,
public String button1_action() {
// TODO: Process the button click action. Return value is a navigation
// case name where null will return to the same page.
log("button clicked...");
return null;
}
--
When i deployed my project. I did get a page with the fourth column as a button, but the action method was still not called.
Did i do something wrong?.
Thanks,
Adi.
# 10
What is the name of your page?
# 11
For your convenience, I've created a blog http://blogs.sun.com/roller/page/winston?entry=dynamic_button_tableYou can download the sample application from here.- Winston
# 12
Hi Winston,Thanks about it.Adi.
# 13
Hi creator folks,
I had quite the same problematic, except that I'm not working inside a datatable, so I can't use stuff like "getValue("#{currentRow.value[\'TRIP.TRIPID\']}"))". So I tried to bind a actionListener to my ImageHyperlinks as following:
Class[] parameterList = { Class.forName("javax.faces.event.ActionEvent") };
imageHyperlink.setActionListener(getApplication().createMethodBinding("#{Page1.chartsActionListener}", parameterList));
And I well have my chartsActionListener method:
public void chartsActionListener(ActionEvent ae) {
// Business handling here
}
But while executing I still get org.apache.jasper.JasperException error.
By the way I also tried with imageHyperlink.setActionListener(getApplication().createMethodBinding("#{Page1.chartsActionListener}", null));
, same error.
# 14
Well, sorry, I got it to work. The key is the place where you put your code: I was working from prerender() method, and it does not work.
When I called for the dynamic components generation from my getGridPanel1() method everything worked fine!
So, as a bonus, here's an example for adding both action and actionListener to a ImageHyperlink component:
// Add the binding to the action method: public String imageHyperlink1_action()
imageHyperlink.setAction(getApplication().createMethodBinding("#{Page1.imageHyperlink1_action}", null));
// Add the binding to the actionListener method: public void chartsActionListener(ActionEvent ae)
Class[] parameterList = { Class.forName("javax.faces.event.ActionEvent") };
imageHyperlink.setActionListener(getApplication().createMethodBinding("#{Page1.chartsActionListener}", parameterList));
// Add the ImageHyperlink to the GridPanel
gridPanel1.getChildren().add(imageHyperlink);
# 15
Hi ValeredejardinI'm not sure if You still follow this thread but it's never stupid to try.what's the actual difference between binding to action method and actionListener?thanks !dElay
dElaya at 2007-7-21 15:00:06 >
