Im implementing some generic components and I just wonder if my design patters makes sense and if there are any improvements that can be made. E.g., here is a generic panel that can be used to filter stuff:
/**
* Abstract class for textfields used for filtering. When overriding abstract method onUpdateFilter, the first thing
* that must be done is to set the paramsobject, or else filtering wont work.
* @author fred
*
*/
public abstract class FilterFormPanel extends Panel {
private static final long serialVersionUID = 1L;
private FilterForm filterForm;
private Object paramsObject; //this is object because paramsobjects differ depending on entity type
public FilterFormPanel(String id) {
super(id);
filterForm = new FilterForm("filterForm");
add(filterForm);
}
public String getFilterString(){
return filterForm.getFilterString();
}
public void setParamsObject(Object paramsObject){
this.paramsObject = paramsObject;
}
/**
*For developers to implement in class that contains the correct references to params and facade objects, dataviews etc.
*e.g. they could do params.setFilter(<reference to an instance of this class>.getFilterString() and ajax stuff too)
*/
public abstract void onUpdateFilter(AjaxRequestTarget target, Object paramsObject);
private class FilterForm extends Form<Void> {
private static final long serialVersionUID = 1L;
private transient String filterString;
public FilterForm(String id) {
super(id);
final TextField<String> filterTextField = new TextField<String>("filterTextField", new PropertyModel<String>(this, "filterString")); //textField for user to enter filter string
add(filterTextField);
add(new AjaxButton("filterButton") { //button to click for performing overriden method
private static final long serialVersionUID = 1L;
@Override
protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
onUpdateFilter(target, paramsObject);
}
});
}
public String getFilterString(){
return filterString;
}
}
}
Used as follows in another class:
filterFormPanel = new FilterFormPanel("filterFormPanel"){
private static final long serialVersionUID = 1L;
@Override
public void onUpdateFilter(AjaxRequestTarget target, Object paramsObject) {
filterFormPanel.setParamsObject(params);
params.setFilterString(filterFormPanel.getFilterString());
//ajax stuff
target.addComponent(dataViewContainer);
nav.setVisible(dataProvider.size()!=0);
target.addComponent(nav);
emptyLabel.setVisible(dataProvider.size()==0);
target.addComponent(emptyLabel);
}
};
settingsContainer.add(filterFormPanel);
Its kind of annoying that one is forced to use the setParamsObject method first thing when one overrides the method. Is there a nicer way of achieving a reference to that object? And is this is general a sane way of implementing reusable and relatively generic components in wicket? Any feedback would be greatly appreciated, Im sure theres room for improvement here.
EDIT I: Just for some context, what Im doing is Im implementing pages like these
where I present the user with a dataview and options for filtering it. There are lots of pages for lots of different entities, but the GUI components can and should be made as generic as possible as to not violate DRY. The example code is obviously the filter textfield and button part of the page.
EDIT II: I want this component to be even more loosely coupled if possible, e.g. make it able to do completely different things, not just modifying a params object (say, e.g. have another case where I need to update TWO params objects, then I wont be able to use this panel). The onSubmit method in the form as it is now requires a reference to the objects to be used in the overriden method are known beforehand. Is there any way to not have it that way or set the presence and/or types of those objects dynamically?
EDIT III: The point is that this panels core function really is only to allow the user to
- enter a string
- notify and give access to that string to some other part of the system when the user clicks the button.
What that "other part of the system" does with the string should not really have to concern this panel, but as it is now, it is coupled to the params object upon which "the other part of the system" must perform some operation. It is this coupling I would like to get rid of if possible. I might as well want to use the string from this panel for just printing to console or use it for some other arbitrary task.