Keep Table sorted

I usually try to separate the display of my data from the logic that modifies it. So my UI controller should not know that some data is displayed in a Table and only works with the Container interface.

However, when adding an item to the Container, it is added at the end. Is there
a simple
way to trigger Table.sort() when the container changes? I tried

table.addItemSetChangeListener(new ItemSetChangeListener() { @Override public void containerItemSetChange(ItemSetChangeEvent event) { table.sort(); } }); but this causes a StackOverflowError because Table.sort() emits an ItemSetChangeEvent as well…

I mean, sure, I can create another interface (or rather, a few dozen for my whole application), inject that into my controller and hide the whole Container behind that. But I wonder whether there is something simple I overlooked.

Seems like something that should be quite easy to do as it sounds like a common use case.
I unfortunately don’t have an environment to test if there is a simple solution for it but just a few ideas i had to tackle this problem:

  1. Try to use the ItemSetChangeListener of the container not the table though i would think that sorting the table might also trigger this listener.
  2. Create a custom Container extending the one you’re using and override the addItem Method (or whatever method you’re using) and add the call to sort in the overriden method
  3. Just call sort everytime after you call addItem (simple but not that good looking)
  4. Create logik which block the call of table.sort() inside the Listener for a few milliseconds to avoid the look, like thread which sets a boolean to false for a few seconds. (Probably quite dirty)

Again this sounds like such a common use case that there is probably a much better solution…

Hi Marius,

thanks for your reply.

  1. Results in a stack overflow as well (I thought it would as I think the Container methods on a Field simply forward to the underlying Container).
  2. I don’t like extending Containers that much because I use multiple implementations and this would require an extended Container for each one I use. I could certainly live with that but then the Container doesn’t know what to sort on which is why the problem exists in the first place. The sorted properties are part of the Table, not the Container.
  3. This would create a slightly tighter dependency of my controllers to the representation of the data. This is currently my favorite solution. The purpose of my original post was to find alternatives to that.
  4. No! :slight_smile:

So i tested it myself a bit because i found this problem quite interesting and actually this:

            @Override
            public void containerItemSetChange(ItemSetChangeEvent event) {
                if(somebool){
                    somebool = false;
                    cont.sort(new Object[]{"test"}, new boolean[]
{true});
                    somebool = true;
                }
            }

seems to work just fine. Still not sure if its the best solution for this problem but at least its simple, doesn’t need code spreaded over multiple classes and doesn’t involve extending classes.

If your sorted properties are constant, that’s a viable solution. However if the table allows user defined sorting, see the second half of 2. of my previous post.

I think, the properties to sort should be part of the Container just like filters are. Currently it’s a bit inconsistent.

Again this might not be what you’re really looking for but you could detect what columns are currently sorted and which way like this:

[code]
table.addHeaderClickListener(new HeaderClickListener() {

        @Override
        public void headerClick(HeaderClickEvent event) {
            if(event.getPropertyId().equals(tosort)){
                ascsort = !ascsort;
            }else{
                tosort = event.getPropertyId();
                ascsort = true;
            }
        }
    });

[/code]then you can later sort by tosort with the setting ascsort. There also is a way to get the currently sorted column ids using table.getSortColumnIds but not which way they are currently sorted.