Reputation: 225
I get an exception from Wicket 1.4.11 reading:
2010-11-03 17:44:51,971 [http-8080-1] ERROR org.apache.wicket.RequestCycle - Method onFormSubmitted of interface org.apache.wicket.markup.html.form.IFormSubmitListener targeted at component [MarkupContainer [Component id = customer]] threw an exception
org.apache.wicket.WicketRuntimeException: Method onFormSubmitted of interface
org.apache.wicket.markup.html.form.IFormSubmitListener targeted at component [MarkupContainer [Component id = customer]] threw an exception at org.apache.wicket.RequestListenerInterface.invoke(RequestListenerInterface.java:193)
...
Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
Caused by: java.lang.IllegalStateException: This method can only be called on a component that has already been added to its parent.
at org.apache.wicket.Component.replaceWith(Component.java:2804)
at no.magge.iumb.web.crm.customers.PrivateCustomerTab$1.onSubmit(PrivateCustomerTab.java:34)
at org.apache.wicket.markup.html.form.Form.delegateSubmit(Form.java:1565)
This happened when I clicked the cancel_btn
of a form in a panel in a tabbedpanel in a tabbedpanel... Here is the code for cancel_btn
:
public class PrivateCustomerTab extends Panel {
private static final long serialVersionUID = 16L;
protected Panel getCurrentPanel() {
return this;
}
public PrivateCustomerTab(String id, long customerId, final Panel backPanel) {
super(id);
final PrivateCustomerForm form = new PrivateCustomerForm("customer", customerId) {
private static final long serialVersionUID = 4L;
@Override
protected void onSubmit() {
System.out.println("\n\n(formsubmit) HELLO THERE MY PARENT IS: " + getParent() + "\n\n");
if (customerId!=0) {
PrivateCustomerTab.this.replaceWith(new PrivateCustomerTab("panel", customerId, backPanel));
}
}
};
add(form);
Button cancelButton = new Button("cancel_btn", new ResourceModel("cancel")) {
private static final long serialVersionUID = 18L;
@Override
public void onSubmit() {
System.out.println("\n\n(cancelsubmit) HELLO THERE MY PARENT IS: " + getParent() + "\n\n");
if (backPanel!=null) {
// PrivateCustomerTab.this.replace(backPanel);
getCurrentPanel().replaceWith(new CustomerListTab("panel"));
}
}
};
cancelButton.setVisible(backPanel!=null);
form.add(cancelButton);
}
}
I've been trying various way to get the current panel, the one I want to replace. One way is using the getCurrentPanel()
method which just returns this
from the panel class. Another way is doing PrivateCustomerTab.this.replaceWith(...)
, and I've also tried getParent().getParent().replaceWith(...)
. These all give me the message that I cannot replace something that isn't added to its parent.
I think I must be misunderstanding some key concept here. Maybe forms are processed before my panel is added to its parent, meaning I cannot replace the panel in cancel_btn
's onSubmit()
?
I've tried Googling my way and looking for something about it in my copy of Wicket in Action. Please help me understand... thanks!
Upvotes: 0
Views: 7114
Reputation: 225
Figured this one out - newbie mistake (again), I guess.
What happens is that the forms onSubmit()
is called before the cancel_btn
's onSubmit()
. Since the first these methods replaces the panel, naturally the second time one tries to replace that same panel it's not added to a parent any more.
To solve it I moved my forms onSubmit()
code into the my save buttons onSubmit()
. By doing this there is only 1 onSubmit()
method called, depending on what button was clicked.
Upvotes: 0
Reputation: 180
It is not really about finding the right panel. That seems to be ok. All three calls do seem to find the same panel.
It is about, were the panel itself is added to. To replace itself with something els a component needs to ask the parent, were it is added to. Then it ask its parent to forget about itself and choose the given Component as a child.
So wicket basically complains that the panel is not added to any component.
Was the component hierachy changed in the mean time?
Upvotes: 1