use of com.codename1.rad.models.EntityList.EntityListEvent in project CodeRAD by shannah.
the class EntityListTest method testTransactions.
private void testTransactions() throws Exception {
EntityList el = new EntityList();
Entity bob = new BaseEntity();
Entity gary = new BaseEntity();
Entity june = new BaseEntity();
class Stats {
private Object data;
private int count;
private void reset() {
data = null;
count = 0;
}
}
// Warm it up.. make sure no NPEs or anything
el.add(bob);
el.add(gary);
el.remove(bob);
el.remove(gary);
Stats stats = new Stats();
ActionListener<EntityListEvent> l1 = evt -> {
if (evt instanceof EntityAddedEvent || evt instanceof EntityRemovedEvent) {
stats.count++;
stats.data = evt;
}
};
el.addActionListener(l1);
el.add(bob);
assertEqual(1, stats.count);
assertTrue(stats.data instanceof EntityAddedEvent);
assertEqual(1, el.size());
EntityAddedEvent eae = (EntityAddedEvent) stats.data;
assertEqual(bob, eae.getEntity());
assertNull(eae.getTransaction(), "EntityAddedEvent not in transaction should return null for getTransaction()");
stats.reset();
el.startTransaction();
assertEqual(0, stats.count);
assertNull(stats.data);
el.remove(bob);
assertEqual(1, stats.count);
assertTrue(stats.data instanceof EntityRemovedEvent);
assertEqual(0, el.size());
EntityRemovedEvent ere = (EntityRemovedEvent) stats.data;
assertEqual(bob, ere.getEntity());
assertNotNull(ere.getTransaction(), "EntityRemovedEvent inside transaction should return non-null for getTransaction()");
Throwable t = null;
try {
el.startTransaction();
} catch (IllegalStateException ex) {
t = ex;
}
assertTrue(t instanceof IllegalStateException, "Starting a transaction while another one is active should raise an IllegalStateException");
el.commitTransaction();
el.removeActionListener(l1);
l1 = evt -> {
if (evt instanceof EntityAddedEvent || evt instanceof EntityRemovedEvent || evt instanceof TransactionEvent) {
stats.count++;
stats.data = evt;
}
};
el.addActionListener(l1);
stats.reset();
el.startTransaction();
assertEqual(1, stats.count);
assertTrue(stats.data instanceof TransactionEvent);
TransactionEvent te = (TransactionEvent) stats.data;
assertTrue(te.isEmpty());
assertTrue(!te.isComplete());
stats.reset();
el.add(bob);
assertEqual(1, stats.count);
assertTrue(stats.data instanceof EntityAddedEvent);
eae = (EntityAddedEvent) stats.data;
assertEqual(bob, eae.getEntity());
assertEqual(eae.getTransaction(), te, "EntityAddedEvent.getTransaction() should return same TransactionEvent from startTransaction");
stats.reset();
el.add(gary);
assertEqual(1, stats.count);
assertTrue(stats.data instanceof EntityAddedEvent);
eae = (EntityAddedEvent) stats.data;
assertEqual(gary, eae.getEntity());
stats.reset();
el.commitTransaction();
assertEqual(1, stats.count);
assertTrue(stats.data instanceof TransactionEvent);
te = (TransactionEvent) stats.data;
assertEqual(2, te.size());
assertTrue(te.isComplete());
assertEqual(bob, te.get(0).getEntity());
assertEqual(gary, te.get(1).getEntity());
t = null;
try {
el.commitTransaction();
} catch (IllegalStateException ex) {
t = ex;
}
assertTrue(t instanceof IllegalStateException, "commitTransaction() on list with no current transaction should raise an IllegalStateException");
el.startTransaction();
stats.reset();
el.clear();
assertEqual(0, el.size(), "EntityList.add() and EntityList.remove() should immediately change the list even if transaction is in progress");
assertEqual(2, stats.count, "EntityList.clear() should trigger remove events for each item in list");
el.commitTransaction();
assertEqual(0, el.size());
assertEqual(3, stats.count);
assertTrue(stats.data instanceof TransactionEvent, "commitTransaction() didn't fire a transaction event");
te = (TransactionEvent) stats.data;
assertEqual(2, te.size(), "TransactionEvent size() should reflect the number of add or remove operations in transaction.");
assertEqual(bob, te.get(0).getEntity());
assertEqual(gary, te.get(1).getEntity());
}
use of com.codename1.rad.models.EntityList.EntityListEvent in project CodeRAD by shannah.
the class EntityList method toListModel.
public ListModel<T> toListModel() {
return new ListModel<T>() {
private int selectedIndex = -1;
private List<SelectionListener> selectionListeners;
@Override
public T getItemAt(int i) {
return EntityList.this.get(i);
}
@Override
public int getSize() {
return EntityList.this.size();
}
@Override
public int getSelectedIndex() {
return selectedIndex;
}
@Override
public void setSelectedIndex(int i) {
if (selectedIndex != i) {
int old = selectedIndex;
selectedIndex = i;
if (selectionListeners != null && !selectionListeners.isEmpty()) {
List<SelectionListener> toSend = new ArrayList<>();
for (SelectionListener l : toSend) {
l.selectionChanged(old, selectedIndex);
}
}
}
}
class DataChangedListenerWrapper implements ActionListener<EntityListEvent> {
DataChangedListener l;
DataChangedListenerWrapper(DataChangedListener l) {
this.l = l;
}
@Override
public void actionPerformed(EntityListEvent entityListEvent) {
if (entityListEvent instanceof EntityAddedEvent) {
EntityAddedEvent e = (EntityAddedEvent) entityListEvent;
l.dataChanged(DataChangedListener.ADDED, e.getIndex());
} else if (entityListEvent instanceof EntityRemovedEvent) {
EntityRemovedEvent e = (EntityRemovedEvent) entityListEvent;
l.dataChanged(DataChangedListener.REMOVED, e.getIndex());
}
}
}
private List<DataChangedListenerWrapper> dataChangedListenerWrappers;
@Override
public void addDataChangedListener(DataChangedListener dataChangedListener) {
if (dataChangedListenerWrappers == null) {
dataChangedListenerWrappers = new ArrayList<>();
}
DataChangedListenerWrapper w = new DataChangedListenerWrapper(dataChangedListener);
dataChangedListenerWrappers.add(w);
EntityList.this.addActionListener(w);
}
@Override
public void removeDataChangedListener(DataChangedListener dataChangedListener) {
DataChangedListenerWrapper w = null;
if (dataChangedListenerWrappers == null || dataChangedListenerWrappers.isEmpty())
return;
for (DataChangedListenerWrapper candidate : dataChangedListenerWrappers) {
if (candidate.l == dataChangedListener) {
w = candidate;
break;
}
}
if (w == null)
return;
EntityList.this.removeActionListener(w);
}
@Override
public void addSelectionListener(SelectionListener selectionListener) {
if (selectionListeners == null)
selectionListeners = new ArrayList<>();
selectionListeners.add(selectionListener);
}
@Override
public void removeSelectionListener(SelectionListener selectionListener) {
if (selectionListeners == null)
return;
selectionListeners.remove(selectionListener);
}
@Override
public void addItem(T o) {
EntityList.this.add((T) o);
}
@Override
public void removeItem(int i) {
Object o = EntityList.this.get(i);
if (o != null) {
EntityList.this.remove((T) o);
}
}
};
}
use of com.codename1.rad.models.EntityList.EntityListEvent in project CodeRAD by shannah.
the class EntityList method toMultipleSelectionListModel.
public MultipleSelectionListModel<T> toMultipleSelectionListModel() {
return new MultipleSelectionListModel<T>() {
private List<SelectionListener> selectionListeners;
private Set<Integer> selectedIndices = new HashSet<>();
@Override
public void addSelectedIndices(int... ints) {
List<Integer> added = new ArrayList();
for (int i : ints) {
if (selectedIndices.contains(i))
continue;
selectedIndices.add(i);
added.add(i);
}
if (selectionListeners != null && !selectionListeners.isEmpty() && !added.isEmpty()) {
List<SelectionListener> toSend = new ArrayList<>(selectionListeners);
for (Integer i : added) {
for (SelectionListener l : toSend) {
l.selectionChanged(-1, i);
}
}
}
}
@Override
public void removeSelectedIndices(int... ints) {
List<Integer> removed = new ArrayList<>();
for (int i : ints) {
if (!selectedIndices.contains(i)) {
continue;
}
selectedIndices.remove(i);
removed.add(i);
}
if (selectionListeners != null && !selectionListeners.isEmpty() && !removed.isEmpty()) {
List<SelectionListener> toSend = new ArrayList<>(selectionListeners);
for (Integer i : removed) {
for (SelectionListener l : toSend) {
l.selectionChanged(i, -1);
}
}
}
}
@Override
public void setSelectedIndices(int... ints) {
int[] existing = getSelectedIndices();
Set<Integer> existingInts = new HashSet<>();
Set<Integer> newInts = new HashSet<>();
Set<Integer> toAdd = new HashSet<>();
Set<Integer> toRemove = new HashSet<>();
for (int i : ints) {
newInts.add(i);
}
for (int i : existing) {
existingInts.add(i);
}
for (int i : newInts) {
if (!existingInts.contains(i)) {
toAdd.add(i);
}
}
for (int i : existingInts) {
if (!newInts.contains(i)) {
toRemove.add(i);
}
}
if (!toRemove.isEmpty()) {
int[] toRemoveArr = new int[toRemove.size()];
int index = 0;
for (Integer remI : toRemove) {
toRemoveArr[index++] = remI;
}
removeSelectedIndices(toRemoveArr);
}
if (!toAdd.isEmpty()) {
int[] toAddArr = new int[toAdd.size()];
int index = 0;
for (Integer addI : toAdd) {
toAddArr[index++] = addI;
}
addSelectedIndices(toAddArr);
}
}
@Override
public int[] getSelectedIndices() {
List<Integer> ints = new ArrayList<>(selectedIndices);
Collections.sort(ints);
int[] out = new int[ints.size()];
int index = 0;
for (Integer i : ints) {
out[index++] = i;
}
return out;
}
@Override
public T getItemAt(int i) {
return EntityList.this.get(i);
}
@Override
public int getSize() {
return EntityList.this.size();
}
@Override
public int getSelectedIndex() {
if (selectedIndices.isEmpty())
return -1;
return selectedIndices.iterator().next();
}
@Override
public void setSelectedIndex(int i) {
if (i < 0) {
if (!selectedIndices.isEmpty()) {
removeSelectedIndices(getSelectedIndices());
}
} else
setSelectedIndices(i);
}
class DataChangedListenerWrapper implements ActionListener<EntityListEvent> {
DataChangedListener l;
DataChangedListenerWrapper(DataChangedListener l) {
this.l = l;
}
@Override
public void actionPerformed(EntityListEvent entityListEvent) {
if (entityListEvent instanceof EntityAddedEvent) {
EntityAddedEvent e = (EntityAddedEvent) entityListEvent;
l.dataChanged(DataChangedListener.ADDED, e.getIndex());
} else if (entityListEvent instanceof EntityRemovedEvent) {
EntityRemovedEvent e = (EntityRemovedEvent) entityListEvent;
l.dataChanged(DataChangedListener.REMOVED, e.getIndex());
}
}
}
private List<DataChangedListenerWrapper> dataChangedListenerWrappers;
@Override
public void addDataChangedListener(DataChangedListener dataChangedListener) {
if (dataChangedListenerWrappers == null) {
dataChangedListenerWrappers = new ArrayList<>();
}
DataChangedListenerWrapper w = new DataChangedListenerWrapper(dataChangedListener);
dataChangedListenerWrappers.add(w);
EntityList.this.addActionListener(w);
}
@Override
public void removeDataChangedListener(DataChangedListener dataChangedListener) {
DataChangedListenerWrapper w = null;
if (dataChangedListenerWrappers == null || dataChangedListenerWrappers.isEmpty())
return;
for (DataChangedListenerWrapper candidate : dataChangedListenerWrappers) {
if (candidate.l == dataChangedListener) {
w = candidate;
break;
}
}
if (w == null)
return;
EntityList.this.removeActionListener(w);
}
@Override
public void addSelectionListener(SelectionListener selectionListener) {
if (selectionListeners == null)
selectionListeners = new ArrayList<>();
selectionListeners.add(selectionListener);
}
@Override
public void removeSelectionListener(SelectionListener selectionListener) {
if (selectionListeners == null || selectionListeners.isEmpty())
return;
selectionListeners.remove(selectionListener);
}
@Override
public void addItem(T o) {
EntityList.this.add((T) o);
}
@Override
public void removeItem(int i) {
Object o = EntityList.this.get(i);
if (o != null) {
EntityList.this.remove((T) o);
}
}
};
}
Aggregations