here is what i came up with and works very , very nice:
Code:
public interface DependentRule {
public String getFieldName();
public Object calculate(List<ListStore<BaseModel>> sources, int currentIndex) throws Exception;
public abstract class SimpleDependentRule implements DependentRule{
protected final String name;
public SimpleDependentRule(String name) {
this.name = name;
}
@Override
public String getFieldName(){
return name;
}
public Object calculate(List<ListStore<BaseModel>> sources, int currentIndex) throws Exception{
List<BaseModel> bms = new ArrayList();
for(ListStore<BaseModel> source : sources){
bms.add(source.getAt(currentIndex));
}
return calculate( bms );
}
public abstract Object calculate(List<BaseModel> sources);
protected double autoFormat(double d){
String format = NumberFormat.getDecimalFormat().format(d);
return Double.parseDouble(format);
}
}
}
public class DependentListStore extends ListStore<BaseModel>{
public DependentListStore(List<ListStore<BaseModel>> originals){
sources = originals;
initLoaded();
listener = new StoreListener<BaseModel>(){
@Override
public void storeAdd(StoreEvent<BaseModel> se) {
setStoreAs(se, Boolean.TRUE);
if (!loaded.contains(Boolean.FALSE)) {
calculateValues();
}
}
@Override
public void storeClear(StoreEvent<BaseModel> se) {
removeAll();
setStoreAs(se, Boolean.FALSE);
}
@Override
public void storeDataChanged(StoreEvent<BaseModel> se) {
setStoreAs(se, Boolean.TRUE);
if (!loaded.contains(Boolean.FALSE)) {
calculateValues();
}
}
private void setStoreAs(StoreEvent<BaseModel> se, Boolean b) {
int indexOf = sources.indexOf(se.getStore());
if (indexOf==-1) {
return ;
}
loaded.set(indexOf, b);
}
};
for(ListStore<BaseModel> store : sources){
store.addStoreListener(listener);
}
}
private void initLoaded() {
for(@SuppressWarnings("unused") Store<BaseModel> store : sources){
loaded.add(Boolean.FALSE);
}
}
private void calculateValues() {
removeAll();//just to confirm
int currentSize = calcSize();
all = new ArrayList<BaseModel>(currentSize);
applyRules(currentSize);
for (BaseModel m : all) {
registerModel(m);
}
if (filtersEnabled) {
filtersEnabled = false;
applyFilters(filterProperty);
}
if (storeSorter != null) {
applySort(true);
}
fireEvent(DataChanged, createStoreEvent());
}
private void applyRules(int currentSize) {
for(int i=0;i<currentSize;i++){
applyRulesToIndex(i);
}
}
public DependentListStore setRules(DependentRule... rules) {
this.rules = GuiUtils.newList(rules);
return this;
}
private void applyRulesToIndex(int i) {
BaseModel tmp = new BaseModel();
for(DependentRule rule : rules){
try{
tmp.set(rule.getFieldName(), rule.calculate(sources,i));
}catch(Exception e){
//same as if we put a null under that fieldName
}
}
all.add(i, tmp);
}
private int calcSize() {
List<Integer> sizes = new ArrayList<Integer>();
for(ListStore<BaseModel> store : sources){
sizes.add( store.getCount());
}
int currentSize = Collections.max(sizes);
return currentSize;
}
}
please dont hesitate with any comments or suggestions for improvements!
thanks