Search in sources :

Example 1 with EntityAddedEvent

use of com.codename1.rad.models.EntityList.EntityAddedEvent 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());
}
Also used : AbstractTest(com.codename1.testing.AbstractTest) Observer(java.util.Observer) TransactionEvent(com.codename1.rad.models.EntityList.TransactionEvent) EntityAddedEvent(com.codename1.rad.models.EntityList.EntityAddedEvent) EntityRemovedEvent(com.codename1.rad.models.EntityList.EntityRemovedEvent) EntityList(com.codename1.rad.models.EntityList) BaseEntity(com.codename1.rad.models.BaseEntity) EntityListEvent(com.codename1.rad.models.EntityList.EntityListEvent) ActionListener(com.codename1.ui.events.ActionListener) Entity(com.codename1.rad.models.Entity) BaseEntity(com.codename1.rad.models.BaseEntity) Entity(com.codename1.rad.models.Entity) EntityList(com.codename1.rad.models.EntityList) BaseEntity(com.codename1.rad.models.BaseEntity) EntityListEvent(com.codename1.rad.models.EntityList.EntityListEvent) TransactionEvent(com.codename1.rad.models.EntityList.TransactionEvent) EntityRemovedEvent(com.codename1.rad.models.EntityList.EntityRemovedEvent) EntityAddedEvent(com.codename1.rad.models.EntityList.EntityAddedEvent)

Example 2 with EntityAddedEvent

use of com.codename1.rad.models.EntityList.EntityAddedEvent 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);
            }
        }
    };
}
Also used : DataChangedListener(com.codename1.ui.events.DataChangedListener) MultipleSelectionListModel(com.codename1.ui.list.MultipleSelectionListModel) ListModel(com.codename1.ui.list.ListModel) SelectionListener(com.codename1.ui.events.SelectionListener)

Example 3 with EntityAddedEvent

use of com.codename1.rad.models.EntityList.EntityAddedEvent in project CodenameOne by codenameone.

the class RADEntityListAddRemoveInvalidateSample method start.

public void start() {
    if (current != null) {
        current.show();
        return;
    }
    // An entity for the rows our our list view.
    class Person extends Entity {
    }
    entityTypeBuilder(Person.class).string(Thing.name).factory(cls -> {
        return new Person();
    }).build();
    // A remove row action that will be added to each row
    ActionNode removeRow = UI.action(UI.icon(FontImage.MATERIAL_DELETE));
    // An internal list we will use to store the rows of the entitylist
    ArrayList internalList = new ArrayList();
    EntityList profileList = new EntityList() {

        /**
         * Override createInternalList() so that we can use our own data structure
         * for storing this list.  This is contrived to allow us to test the
         * invalidate() method.
         */
        @Override
        protected List createInternalList() {
            return internalList;
        }
    };
    // A list node to wrap our action and pass it to our view
    ListNode node = new ListNode(// of the list.
    UI.actions(ProfileListView.ACCOUNT_LIST_ROW_ACTIONS, removeRow));
    // A ProfileListView to render the list.
    // See https://shannah.github.io/CodeRAD/javadoc/com/codename1/rad/ui/entityviews/ProfileListView.html
    ProfileListView listView = new ProfileListView(profileList, node, 10);
    listView.setScrollableY(true);
    // Create a controller for the ProfileListView so that we can handle actions fired by the view.
    // Normally we'd do this in the FormController but since this sample doesn't have one
    // we create a ViewController for the ProfileListView directly.
    ViewController controller = new ViewController(null);
    controller.setView(listView);
    // Button to add rows to the list
    Button addRow = new Button(FontImage.MATERIAL_ADD);
    // Button to clear the list
    Button clear = new Button("Clear");
    addRow.addActionListener(evt -> {
        // "Add" button clicked.
        // Create new person and add to the list
        Person p = new Person();
        p.set(Thing.name, "Row " + profileList.size());
        profileList.add(p);
    // This will trigger an EntityAddedEvent which will allow
    // the ProfileListView to synchronize
    });
    clear.addActionListener(evt -> {
        // "Clear" button clicked
        // We could have called profileList.clear()
        // but this would send EntityRemoved events for each row removed
        // which is inefficient.  Instead we'll clear the elements in
        // the internal list directly, and then call invalidate()
        // so that the ProfileListView knows to resynchronize its state.
        internalList.clear();
        profileList.invalidate();
    });
    controller.addActionListener(removeRow, evt -> {
        // The "Remove" button was clicked on a row.
        profileList.remove(evt.getEntity());
    });
    Form hi = new Form("Hi World", new BorderLayout());
    hi.add(NORTH, GridLayout.encloseIn(2, clear, addRow));
    hi.add(CENTER, listView);
    hi.show();
}
Also used : Toolbar(com.codename1.ui.Toolbar) BoxLayout(com.codename1.ui.layouts.BoxLayout) EntityTypeBuilder.entityTypeBuilder(com.codename1.rad.models.EntityTypeBuilder.entityTypeBuilder) Form(com.codename1.ui.Form) NetworkEvent(com.codename1.io.NetworkEvent) ArrayList(java.util.ArrayList) ListNode(com.codename1.rad.nodes.ListNode) GridLayout(com.codename1.ui.layouts.GridLayout) Display(com.codename1.ui.Display) FontImage(com.codename1.ui.FontImage) Label(com.codename1.ui.Label) Button(com.codename1.ui.Button) CN(com.codename1.ui.CN) ViewController(com.codename1.rad.controllers.ViewController) UI(com.codename1.rad.ui.UI) Entity(com.codename1.rad.models.Entity) Resources(com.codename1.ui.util.Resources) EntityList(com.codename1.rad.models.EntityList) IOException(java.io.IOException) ActionNode(com.codename1.rad.nodes.ActionNode) Log(com.codename1.io.Log) BorderLayout(com.codename1.ui.layouts.BorderLayout) ProfileListView(com.codename1.rad.ui.entityviews.ProfileListView) UIManager(com.codename1.ui.plaf.UIManager) List(java.util.List) Dialog(com.codename1.ui.Dialog) Thing(com.codename1.rad.schemas.Thing) Entity(com.codename1.rad.models.Entity) BorderLayout(com.codename1.ui.layouts.BorderLayout) ViewController(com.codename1.rad.controllers.ViewController) Button(com.codename1.ui.Button) Form(com.codename1.ui.Form) ActionNode(com.codename1.rad.nodes.ActionNode) ArrayList(java.util.ArrayList) EntityList(com.codename1.rad.models.EntityList) ProfileListView(com.codename1.rad.ui.entityviews.ProfileListView) ListNode(com.codename1.rad.nodes.ListNode)

Example 4 with EntityAddedEvent

use of com.codename1.rad.models.EntityList.EntityAddedEvent 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);
            }
        }
    };
}
Also used : DataChangedListener(com.codename1.ui.events.DataChangedListener) MultipleSelectionListModel(com.codename1.ui.list.MultipleSelectionListModel) SelectionListener(com.codename1.ui.events.SelectionListener)

Example 5 with EntityAddedEvent

use of com.codename1.rad.models.EntityList.EntityAddedEvent in project CodeRAD by shannah.

the class EntityListTest method testGenericList.

private void testGenericList() throws Exception {
    EntityList list = new EntityList();
    assertEqual(0, list.size());
    list.add(new BaseEntity());
    list.add(new BaseEntity());
    list.add(new BaseEntity());
    assertEqual(3, list.size());
    Entity firstEntity = list.get(0);
    assertNotNull(firstEntity);
    list.remove(firstEntity);
    assertEqual(2, list.size());
    class Stats {

        int counter = 0;

        Entity lastAdd;

        Entity lastRemove;

        int added;

        int removed;
    }
    Stats stats = new Stats();
    Observer observer = (o, arg) -> {
        stats.counter++;
    };
    list.addObserver(observer);
    list.notifyObservers();
    assertEqual(stats.counter, 1);
    list.notifyObservers();
    assertEqual(1, stats.counter);
    list.add(new BaseEntity());
    assertEqual(1, stats.counter);
    list.notifyObservers();
    assertEqual(2, stats.counter);
    list.addActionListener(evt -> {
        if (evt instanceof EntityAddedEvent) {
            EntityAddedEvent eae = (EntityAddedEvent) evt;
            stats.added++;
            stats.lastAdd = eae.getEntity();
        } else if (evt instanceof EntityRemovedEvent) {
            EntityRemovedEvent ere = (EntityRemovedEvent) evt;
            stats.removed++;
            stats.lastRemove = ere.getEntity();
        }
    });
    list.add(firstEntity);
    assertEqual(1, stats.added);
    assertEqual(firstEntity, stats.lastAdd);
    list.remove(firstEntity);
    assertEqual(1, stats.removed);
    assertEqual(firstEntity, stats.lastRemove);
}
Also used : AbstractTest(com.codename1.testing.AbstractTest) Observer(java.util.Observer) TransactionEvent(com.codename1.rad.models.EntityList.TransactionEvent) EntityAddedEvent(com.codename1.rad.models.EntityList.EntityAddedEvent) EntityRemovedEvent(com.codename1.rad.models.EntityList.EntityRemovedEvent) EntityList(com.codename1.rad.models.EntityList) BaseEntity(com.codename1.rad.models.BaseEntity) EntityListEvent(com.codename1.rad.models.EntityList.EntityListEvent) ActionListener(com.codename1.ui.events.ActionListener) Entity(com.codename1.rad.models.Entity) BaseEntity(com.codename1.rad.models.BaseEntity) Entity(com.codename1.rad.models.Entity) EntityRemovedEvent(com.codename1.rad.models.EntityList.EntityRemovedEvent) Observer(java.util.Observer) EntityList(com.codename1.rad.models.EntityList) BaseEntity(com.codename1.rad.models.BaseEntity) EntityAddedEvent(com.codename1.rad.models.EntityList.EntityAddedEvent)

Aggregations

Entity (com.codename1.rad.models.Entity)3 EntityList (com.codename1.rad.models.EntityList)3 BaseEntity (com.codename1.rad.models.BaseEntity)2 EntityAddedEvent (com.codename1.rad.models.EntityList.EntityAddedEvent)2 EntityListEvent (com.codename1.rad.models.EntityList.EntityListEvent)2 EntityRemovedEvent (com.codename1.rad.models.EntityList.EntityRemovedEvent)2 TransactionEvent (com.codename1.rad.models.EntityList.TransactionEvent)2 AbstractTest (com.codename1.testing.AbstractTest)2 ActionListener (com.codename1.ui.events.ActionListener)2 DataChangedListener (com.codename1.ui.events.DataChangedListener)2 SelectionListener (com.codename1.ui.events.SelectionListener)2 MultipleSelectionListModel (com.codename1.ui.list.MultipleSelectionListModel)2 Observer (java.util.Observer)2 Log (com.codename1.io.Log)1 NetworkEvent (com.codename1.io.NetworkEvent)1 ViewController (com.codename1.rad.controllers.ViewController)1 EntityTypeBuilder.entityTypeBuilder (com.codename1.rad.models.EntityTypeBuilder.entityTypeBuilder)1 ActionNode (com.codename1.rad.nodes.ActionNode)1 ListNode (com.codename1.rad.nodes.ListNode)1 Thing (com.codename1.rad.schemas.Thing)1