0

ConcurrentModificationException when passing listitem from listbox to another

asked 2011-04-05 02:57:28 +0800

bricecol gravatar image bricecol
43 4

updated 2011-04-05 02:59:42 +0800

Hi,

First, sorry for my english if I make mistakes :)

I have to listboxes, and I would be able to take an item from the first one and put it in the second and vis et versa. I explain myself. I have project model which can be associated with users. So I would to affect user(s) or delete affectation(s).

I have a Zul file like this (simplified) :

<window id="..." apply="....">
  ...
  <listbox id="notAffected"/>
  ... boutons here
  <listbox id="affected"/>
  ...
</window>

So it's very simple.

During onCreate window event in the GenericForwardComposer, I create and put my project user listitems in the not affected listbox and the others in the affected listbox. So this first action works fine.

My problem is that when I use the add and delete buttons, I have an error which appears randomly (it can works many times or only 2/3 times...) :

GRAVE: >>java.util.ConcurrentModificationException
>>	at org.zkoss.zk.ui.AbstractComponent$ChildIter.checkComodification(AbstractComponent.java:2672)
>>	at org.zkoss.zk.ui.AbstractComponent$ChildIter.next(AbstractComponent.java:2650)
>>	at org.zkoss.zul.Listbox$ItemIter.next(Listbox.java:2977)
>>	at com.enee.view.admin.ProjectUsersWindow.onClick$removeBtn(ProjectUsersWindow.java:108)
>>	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
>>	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>>	at java.lang.reflect.Method.invoke(Method.java:616)
>>	at org.zkoss.zk.ui.event.GenericEventListener.onEvent(GenericEventListener.java:81)
>>	at org.zkoss.zk.ui.impl.EventProcessor.process0(EventProcessor.java:206)
>>...

This is an extract of my code (simplified) :

public void onClick$addBtn() {
    this.addBtn.setDisabled(true);

    final Iterator<UserListitem> items = this.usersNotAffectedLbox.getItems().listIterator();
    UserListitem item;

    while (items.hasNext()) {
      item = items.next();

      if (item.isSelected()) {     
        this.usersAffectedLbox.appendChild(item);
        this.usersNotAffectedLbox.removeChild(item);
      }
    }

    this.addBtn.setDisabled(false);
  }

  public void onClick$removeBtn() {
    this.removeBtn.setDisabled(true);

    final Iterator<ProjectUserListitem> items = this.usersAffectedLbox.getItems().listIterator();
    ProjectUserListitem item;

    while (items.hasNext()) {
      item = items.next();

      if (item.isSelected()) {
        this.usersNotAffectedLbox.appendChild(item);
        this.usersAffectedLbox.removeChild(item);
      }
    }

    this.removeBtn.setDisabled(false);
  }

As you can see, I use listiterator, I tried iterator too. At the beggining, I used juste a simple for (Item item : items) { ... }. But I don't know the origin of the error...

Please, could you help me!
Thanks a lot.

delete flag offensive retag edit

1 Reply

Sort by ยป oldest newest

answered 2011-04-05 05:01:49 +0800

bricecol gravatar image bricecol
43 4

I found the solution.

The error is throwed because I move items during I fetch them with an iterator. There are 2 solutions :

1/ Change this :

 final Iterator<ProjectUserListitem> items = this.usersAffectedLbox.getItems().listIterator();

to :
 final Iterator<ProjectUserListitem> items = new ArrayList(this.usersAffectedLbox.getItems()).listIterator();

2/ Do what you have to do if item is selected (persistence), but not move it. At the end of the while, redraw the listboxes.

public void onClick$addBtn() {
    final Role role = (Role) this.rolesCbox.getSelectedItem().getValue();

    final List<UserListitem> items = this.usersNotAffectedLbox.getItems();
    for (final UserListitem uli : items) {
      if (uli.isSelected()) {
        final User user = (User) uli.getValue();
        Provider.getInstance().getProjectController().addUser((Project) this.projectListitem.getValue(), role, user);
      }
    }
  }

private void drawListboxes() {
    this.usersAffectedLbox.getItems().clear();
    this.usersNotAffectedLbox.getItems().clear();

    final Project project = (Project) this.projectListitem.getValue();

    final List<User> notAffected = Provider.getInstance().getProjectDAO().findNotAffectedUsers(project);
    for (final User user : notAffected) {
      this.usersNotAffectedLbox.appendChild(new UserListitem(user));
    }

    final List<ProjectUser> affected = project.getProjectUsers();
    for (final ProjectUser pu : affected) {
      this.usersAffectedLbox.appendChild(new ProjectUserListitem(pu));
    }
  }

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2011-04-05 02:57:28 +0800

Seen: 1,063 times

Last updated: Apr 05 '11

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More