/* * Copyright (c) 2011 PonySDK * Owners: * Luciano Broussal <luciano.broussal AT gmail.com> * Mathieu Barbier <mathieu.barbier AT gmail.com> * Nicolas Ciaravola <nicolas.ciaravola.pro AT gmail.com> * * WebSite: * http://code.google.com/p/pony-sdk/ * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.ponysdk.core.ui.basic; import com.ponysdk.core.ui.basic.event.HasPWidgets; import java.util.Iterator; import java.util.NoSuchElementException; /** * <p> * The main purpose of this specialized collection is to implement * {@link java.util.Iterator#remove()} in a * way that delegates removal to its panel. This makes it much easier for the panel to implement an * iterator that supports removal of widgets. * </p> */ public class PWidgetCollection implements Iterable<PWidget> { private static final int INITIAL_SIZE = 4; private final HasPWidgets parent; private PWidget[] array; private int size; protected PWidgetCollection(final HasPWidgets parent) { this.parent = parent; array = new PWidget[INITIAL_SIZE]; } public void add(final PWidget w) { insert(w, size); } public boolean contains(final PWidget w) { return indexOf(w) != -1; } public PWidget get(final int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException(); } return array[index]; } public int indexOf(final PWidget w) { for (int i = 0; i < size; ++i) { if (array[i] == w) { return i; } } return -1; } public void insert(final PWidget w, final int beforeIndex) { if (beforeIndex < 0 || beforeIndex > size) { if (beforeIndex < 0) throw new IndexOutOfBoundsException("(beforeIndex (" + beforeIndex + ") < 0)"); else throw new IndexOutOfBoundsException("beforeIndex (" + beforeIndex + ") > size (" + size + ")"); } // Realloc array if necessary (doubling). if (size == array.length) { final PWidget[] newArray = new PWidget[array.length * 2]; System.arraycopy(array, 0, newArray, 0, array.length); array = newArray; } ++size; // Move all widgets after 'beforeIndex' back a slot. System.arraycopy(array, beforeIndex, array, beforeIndex + 1, size - 1 - beforeIndex); array[beforeIndex] = w; } @Override public Iterator<PWidget> iterator() { return new WidgetIterator(); } public void remove(final int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException(); } --size; System.arraycopy(array, index + 1, array, index, size - index); array[size] = null; } public boolean remove(final PWidget w) { final int index = indexOf(w); if (index == -1) return false; remove(index); return true; } public int size() { return size; } private class WidgetIterator implements Iterator<PWidget> { private int index = -1; @Override public boolean hasNext() { return index < size - 1; } @Override public PWidget next() { if (index >= size) { throw new NoSuchElementException(); } return array[++index]; } @Override public void remove() { if (index < 0 || index >= size) { throw new IllegalStateException(); } parent.remove(array[index--]); } } }