1. #1
    Sencha User
    Join Date
    Mar 2010
    Posts
    54
    Vote Rating
    0
    petko.ivanov is on a distinguished road

      0  

    Question ListStore question

    ListStore question


    hi,
    i am still a beginner in gxt, so pardon my ignorance if there is an obvious solution to this.
    Here is what i am trying to do.
    I have a few ListStore<BaseModel> that are coming from rpcproxies.
    I am showing them in tables, graphs, etc.
    What i would like to do is create a new ListStore<BaseModel> based on some formula that takes the above ListStores as input. Then this newly create one can also feed a graph or a table.
    Is there a mechanism for this already or should i implement it myself through StoreListeners for example?
    thanks in advance

  2. #2
    Sencha User
    Join Date
    Sep 2007
    Posts
    13,971
    Vote Rating
    132
    sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light

      0  

    Default


    You could copy all models from the first liststore to the second but you also add afilter to the second. This filters out all models you dont want to see in your table.

  3. #3
    Sencha User
    Join Date
    Mar 2010
    Posts
    54
    Vote Rating
    0
    petko.ivanov is on a distinguished road

      0  

    Default


    hi,
    thanks for your reply.
    i am considering something along the same lines.
    here is an example that illustrates this : say i have ListStore foo and bar.
    So i need to create a new ListStore foobar like this :
    foobar.put("foobar", (Double)foo.get(foo")+(Double)bar.get("bar))
    So there will not be necessarily need to copy the original values.
    It would have been trivial if foo and bar had their data from static sources but if it comes from proxies (as is my case), it is a little trickier as i have to hook listeners to the loaders of foo and bar.
    unless there is something already that will do it for free
    but searching for a few days now, has not revealed anything

  4. #4
    Sencha User
    Join Date
    Mar 2010
    Posts
    54
    Vote Rating
    0
    petko.ivanov is on a distinguished road

      0  

    Thumbs up


    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

Thread Participants: 1