I'm building an app that will have *lots* of panels that all follow a very
similar pattern:
They have a form and a static view whose visibility gets toggled when when
you click edit/cancel|save|delete
They display a warning if their model is empty
They pop up a warning when you delete them
They allow you to edit their model
I've written a few and realized that I am cutting and pasting way too much
code; so, I want to build an abstract superclass, but am having trouble
figuring out how. Hopefully someone here may be able to help.
I need my subclasses to add markup to both the static and form components,
which I believe rules out markup inheritance because I would have to use
<wicket:child/> twice and can't imagine wicket being able to figure out what
I meant. The other option I see is to create a panel for both the static
content and the form, and to extend the superclass to specify which panels
to include for each, which seems workable but ugly...
Am I missing something, is there a better way?
The super class I want to write would look something like this, I just can't
figure out how to associate the markup:
public abstract class AttributePanel extends Panel {
WebMarkupContainer staticContainer = new WebMarkupContainer("static");
WebMarkupContainer dynamicContainer = new WebMarkupContainer("dynamic");
AjaxLink editLink;
Form form;
Label unprovisioned = new Label("unprovisioned", "No provisioning data
has been entered for this service, perhaps you should add it now...");;
Attributable attribute; //the model
ComponentFeedbackPanel feedback = new ComponentFeedbackPanel("feedback",
this);
String ConfirmationMsg = "You sure?";
public AttributePanel(final String id, final ModelService service) {
super(id, service);
// add static stuff
staticContainer.setOutputMarkupId(true)
.setOutputMarkupPlaceholderTag(true);
add(staticContainer);
staticContainer.add(unprovisioned.setVisible(false));
if (attribute.getRefItemID()==null) {
unprovisioned.setVisible(true);
}
populateStaticContainer(); //add some components specific to the
subclass
//add dynamic stuff
dynamicContainer.setOutputMarkupId(true)
.setOutputMarkupPlaceholderTag(true);
add(dynamicContainer);
form = new Form("form");
form.add(new AjaxButton("submitButton", form) {
@Override
protected void onSubmit(AjaxRequestTarget target, Form form) {
save();
ServicePanel parent = (ServicePanel)
findParent(ServicePanel.class);
parent.addOrReplace(this);
target.addComponent(parent);
}
@Override
protected void onError(AjaxRequestTarget target, Form form) {
target.addComponent(feedback);
}
});
feedback.setOutputMarkupId(true);
form.add(feedback);
dynamicContainer.add(form);
populateDynamicContainer(); //add some components specific to the
subclass
// Link to show form
editLink = new AjaxLink("edit") {
@Override
public void onClick(AjaxRequestTarget target) {
showForm(target);
}
};
staticContainer.add(editLink);
// Link to return to static view without saving any changes
form.add(new AjaxLink("cancel") {
public void onClick(AjaxRequestTarget target) {
hideForm(target);
}
});
//link to delete attribute
form.add(new Link("deprovision") {
@Override
public void onClick() {
deprovision();
ServicePanel parent = (ServicePanel)
findParent(ServicePanel.class);
parent.addOrReplace(this);
}
}.add(new SimpleAttributeModifier("onclick", "return confirm('"
+getConfirmationMsg()+"'); ")));
}
private void showForm(AjaxRequestTarget target) {
staticContainer.setVisible(true);
dynamicContainer.setVisible(false);
target.addComponent(staticContainer);
target.addComponent(dynamicContainer);
}
private void hideForm(AjaxRequestTarget target) {
staticContainer.setVisible(true);
dynamicContainer.setVisible(false);
target.addComponent(staticContainer);
target.addComponent(dynamicContainer);
}
private String getConfirmationMsg(){
return ConfirmationMsg;
}
abstract void populateStaticContainer();
abstract void populateDynamicContainer();
abstract boolean save();
abstract boolean deprovision();
}
Thanks!
Loren