/******************************************************************************* * Copyright (c) 2007, 2008 Oracle. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0, which accompanies this distribution * and is available at http://www.eclipse.org/legal/epl-v10.html. * * Contributors: * Oracle - initial API and implementation ******************************************************************************/ package org.eclipse.jpt.utility.tests.internal.model.value; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import javax.swing.ListModel; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import org.eclipse.jpt.utility.internal.CollectionTools; import org.eclipse.jpt.utility.model.event.ListChangeEvent; import org.eclipse.jpt.utility.model.listener.ListChangeListener; import org.eclipse.jpt.utility.model.value.ListValueModel; /** * Helper class that keeps an internal list in synch with the * list held by a list value model. */ public class CoordinatedList implements List, ListChangeListener, ListDataListener { private List list = new ArrayList(); public CoordinatedList(ListValueModel listValueModel) { listValueModel.addListChangeListener(ListValueModel.LIST_VALUES, this); for (Iterator stream = listValueModel.iterator(); stream.hasNext(); ) { this.add(stream.next()); } } public CoordinatedList(ListModel listModel) { listModel.addListDataListener(this); for (int i = 0; i < listModel.getSize(); i++) { this.add(i, this.getElementAt(listModel, i)); } } // ********** List implementation ********** public void add(int index, E element) { this.list.add(index, element); } public boolean add(E o) { return this.list.add(o); } public boolean addAll(Collection c) { return this.list.addAll(c); } public boolean addAll(int index, Collection c) { return this.list.addAll(index, c); } public void clear() { this.list.clear(); } public boolean contains(Object o) { return this.list.contains(o); } public boolean containsAll(Collection c) { return this.list.containsAll(c); } public E get(int index) { return this.list.get(index); } public int indexOf(Object o) { return this.list.indexOf(o); } public boolean isEmpty() { return this.list.isEmpty(); } public Iterator iterator() { return this.list.iterator(); } public int lastIndexOf(Object o) { return this.list.lastIndexOf(o); } public ListIterator listIterator() { return this.list.listIterator(); } public ListIterator listIterator(int index) { return this.list.listIterator(index); } public E remove(int index) { return this.list.remove(index); } public boolean remove(Object o) { return this.list.remove(o); } public boolean removeAll(Collection c) { return this.list.removeAll(c); } public boolean retainAll(Collection c) { return this.list.retainAll(c); } public E set(int index, E element) { return this.list.set(index, element); } public int size() { return this.list.size(); } public List subList(int fromIndex, int toIndex) { return this.list.subList(fromIndex, toIndex); } public Object[] toArray() { return this.list.toArray(); } public T[] toArray(T[] a) { return this.list.toArray(a); } // ********** ListChangeListener implementation ********** public void itemsAdded(ListChangeEvent e) { int i = e.getIndex(); for (Iterator stream = this.items(e); stream.hasNext(); ) { this.list.add(i++, stream.next()); } } public void itemsRemoved(ListChangeEvent e) { int i = e.getIndex(); for (Iterator stream = this.items(e); stream.hasNext(); ) { stream.next(); this.list.remove(i); } } public void itemsReplaced(ListChangeEvent e) { int i = e.getIndex(); for (Iterator stream = this.items(e); stream.hasNext(); ) { this.list.set(i++, stream.next()); } } public void itemsMoved(ListChangeEvent e) { CollectionTools.move(this.list, e.getTargetIndex(), e.getSourceIndex(), e.getMoveLength()); } public void listCleared(ListChangeEvent e) { this.list.clear(); } public void listChanged(ListChangeEvent e) { this.list.clear(); CollectionTools.addAll(this.list, this.getSource(e).iterator()); } // ********** ListDataListener implementation ********** public void contentsChanged(ListDataEvent e) { this.list.clear(); ListModel lm = (ListModel) e.getSource(); int size = lm.getSize(); for (int i = 0; i < size; i++) { this.list.add(i, this.getElementAt(lm, i)); } } public void intervalAdded(ListDataEvent e) { ListModel lm = (ListModel) e.getSource(); int start = Math.min(e.getIndex0(), e.getIndex1()); int end = Math.max(e.getIndex0(), e.getIndex1()); for (int i = start; i <= end; i++) { this.list.add(i, this.getElementAt(lm, i)); } } public void intervalRemoved(ListDataEvent e) { int start = Math.min(e.getIndex0(), e.getIndex1()); int end = Math.max(e.getIndex0(), e.getIndex1()); int length = end - start + 1; for (int i = 1; i <= length; i++) { this.list.remove(start); } } // ********** standard methods ********** @Override public boolean equals(Object o) { return this.list.equals(o); } @Override public int hashCode() { return this.list.hashCode(); } @Override public String toString() { return this.list.toString(); } // ********** internal methods ********** /** * minimize the scope of the suppressed warnings.= */ @SuppressWarnings("unchecked") private E getElementAt(ListModel listModel, int index) { return (E) listModel.getElementAt(index); } /** * minimize the scope of the suppressed warnings.= */ @SuppressWarnings("unchecked") private Iterator items(ListChangeEvent event) { return (Iterator) event.items(); } /** * minimize the scope of the suppressed warnings.= */ @SuppressWarnings("unchecked") private ListValueModel getSource(ListChangeEvent event) { return (ListValueModel) event.getSource(); } }