Beta 7. Refresh table contents

Hi there.

I’m using the new data container in v7, but I’m not sure how to get it to refresh on screen when I sort the table contents.

There doesn’t seem to be a refresh for the collection data container.

Tried:

collectionDc.getImmutableItems().sort(…)

and that throws a concurrent update exception.

replaceItem doesn’t force the table to update.

Hi Ray,

The following works for me, including refresh of the connected table:

Comparator<Customer> comparator = Comparator.comparing(Customer::getName);
customersDc.getMutableItems().sort(comparator);

Please provide more details on your use case.

Hi Konstantin.

Yes, I thought some variation of that should work. Odd.

Unfortunately, I’m not set up to look at it right now. I’ll try it again after Version 7.0 has stabilised a bit more.

Okay, back to it.

Here’s the code that I’m trying to run. Note I’ve taken out the bits of the code that attempt to change the list, and it still throws a concurrent exception when I attempt to sort the list.

@Subscribe("stageTemplatesTable.up")
    protected void onStageTemplatesTableUpActionPerformed(ActionPerformedEvent event) {

        StageTemplate currentlySelectedStageTemplate = stageTemplatesDc.getItemOrNull();

        if (currentlySelectedStageTemplate == null
            || currentlySelectedStageTemplate.getSequenceOrder() <= 1) {

            // We're at the top of the list already
            return;
        }


        Optional<StageTemplate> previousStageTemplate = stageTemplatesDc.getMutableItems()
            .stream()
            .filter(stageTemplate -> stageTemplate.getSequenceOrder()
                == currentlySelectedStageTemplate.getSequenceOrder() - 1)
            .findFirst();


        if (! previousStageTemplate.isPresent()) {

            throw new BadStageTemplateSequenceException("Bad sequence number for record --> "
                + currentlySelectedStageTemplate.getId());
        }


        stageTemplatesDc.getMutableItems().sort(Comparator.comparing(StageTemplate::getSequenceOrder));


    }

The exception looks like this:

stack.txt (4.4 KB)

I still cannot reproduce. Could you send me the whole screen controller+XML and the entity class?

ProcessTemplate.java (2.2 KB)
process-templae-edit.xml (3.1 KB)
ProcessTemplateEdit.java (2.6 KB)

Okay, stripping away all the code until I was left with just the sort didn’t fix it, so the problem lies with trying to sort the list somewhere.

However, I thought about it and realised that I didn’t need to sort the list; all I needed to do was swap two items, so I tried this:

    int current = stageTemplatesDc.getItems().indexOf(currentlySelectedStageTemplate);
    int previous = stageTemplatesDc.getItems().indexOf(previousStageTemplate);

    Collections.swap(stageTemplatesDc.getMutableItems(), current, previous);

It’s not particularly elegant because I have to change the sequence numbers on the entities, and then swap them in the data container (since attempting to sort the contents of the container causes a concurrent update error), but it does solve the problem.

Might be nice to have some sort of table up/down buttons built in.

Slightly better:

    Collections.swap(stageTemplatesDc.getMutableItems(),
        stageTemplatesDc.getItemIndex(currentlySelectedStageTemplate),
        stageTemplatesDc.getItemIndex(nextStageTemplate));

Final final answer!

Yes, you can sort the contents of the container, like this:

   stageTemplatesDc.setItems(stageTemplatesDc.getMutableItems()
        .stream()
        .sorted(Comparator.comparing(StageTemplate::getSequenceOrder))
        .collect(Collectors.toList()));

However, this looks like it creates a whole new list again, so it’s probably a lot more efficient to swap the two items unless you really need to sort.

Hi Ray,

After looking at the screen code, I realized what is the reason. You are trying to sort the nested container, and its getMutableItems() method returns the collection that is tightly connected to the underlying collection attribute. It’s now implemented in quite straightforward way and suitable for adding/removing items to the collection, but fails when sorting. We’ll try to fix it, see the issue.

A non-nested CollectionContainer doesn’t have this problem as it is not connected to any property.

At the moment, if you really want to re-sort the collection attribute itself, the only way is to assign the new collection using setItems(), as you did in your last comment.

But if you don’t care how the items are sorted in the entity attribute and only need to display the new order in a UI table connected to the container, use getDisconnectedItems() method as explained in the docs. A collection returned by this method does not apply changes to the entity attribute and allows you to filter and sort items:

@Inject
private CollectionPropertyContainer<StageTemplate> stageTemplatesDc;

@Subscribe("stageTemplatesTable.up")
protected void onStageTemplatesTableUpActionPerformed(ActionPerformedEvent event) {
    // ...
    stageTemplatesDc.getDisconnectedItems().sort(/*...*/);

Notice that the type of injected container is CollectionPropertyContainer.

1 Like