All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.globalmentor.swing.ListListModel Maven / Gradle / Ivy

The newest version!
/*
 * Copyright © 1996-2009 GlobalMentor, Inc. 
 *
 * 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.globalmentor.swing;

import java.util.*;
import javax.swing.*;

/**
 * A list model suitable for a {@link JList} component that delegates to a provided {@link List} object.
 * @author Garret Wilson
 * @see JList
 * @see List
 */
public class ListListModel extends AbstractListModel implements List { //TODO  make sure we don't have to override the iterators---can we assume they will call back to these methods for removal and such?

	/** The list this class proxies. */
	protected final List list;

	/** The list this class proxies. */
	public final List getList() {
		return list;
	}

	/**
	 * List constructor.
	 * @param list The list this list should proxy.
	 */
	public ListListModel(final List list) {
		this.list = list; //save the list
	}

	//ListModel methods

	/**
	 * Returns the length of the list.
	 * @return the length of the list
	 */
	public int getSize() {
		return list.size();
	}

	/**
	 * Returns the value at the specified index.
	 * @param index the requested index
	 * @return the value at index
	 */
	public E getElementAt(int index) {
		return list.get(index);
	}

	//Collection methods

	/**
	 * Returns the number of elements in this collection. If this collection contains more than Integer.MAX_VALUE elements, returns
	 * Integer.MAX_VALUE.
	 * 
	 * @return the number of elements in this collection
	 */
	public int size() {
		return list.size();
	}

	/**
	 * Returns true if this collection contains no elements.
	 *
	 * @return true if this collection contains no elements
	 */
	public boolean isEmpty() {
		return list.isEmpty();
	}

	/**
	 * Returns true if this collection contains the specified element. More formally, returns true if and only if this collection contains at
	 * least one element e such that (o==null ? e==null : o.equals(e)).
	 *
	 * @param o element whose presence in this collection is to be tested.
	 * @return true if this collection contains the specified element
	 * @throws ClassCastException if the type of the specified element is incompatible with this collection (optional).
	 * @throws NullPointerException if the specified element is null and this collection does not support null elements (optional).
	 */
	public boolean contains(Object o) {
		return list.contains(o);
	}

	/**
	 * Returns an iterator over the elements in this collection. There are no guarantees concerning the order in which the elements are returned (unless this
	 * collection is an instance of some class that provides a guarantee).
	 * 
	 * @return an Iterator over the elements in this collection
	 */
	public Iterator iterator() {
		return list.iterator();
	}

	/**
	 * Returns an array containing all of the elements in this collection. If the collection makes any guarantees as to what order its elements are returned by
	 * its iterator, this method must return the elements in the same order.
	 * 

* * The returned array will be "safe" in that no references to it are maintained by this collection. (In other words, this method must allocate a new array * even if this collection is backed by an array). The caller is thus free to modify the returned array. *

* * This method acts as bridge between array-based and collection-based APIs. * * @return an array containing all of the elements in this collection */ public Object[] toArray() { return list.toArray(); } /** * Returns an array containing all of the elements in this collection; the runtime type of the returned array is that of the specified array. If the * collection fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the * size of this collection. *

* * If this collection fits in the specified array with room to spare (i.e., the array has more elements than this collection), the element in the array * immediately following the end of the collection is set to null. This is useful in determining the length of this collection only if the * caller knows that this collection does not contain any null elements.) *

* * If this collection makes any guarantees as to what order its elements are returned by its iterator, this method must return the elements in the same order. *

* * Like the toArray method, this method acts as bridge between array-based and collection-based APIs. Further, this method allows precise control * over the runtime type of the output array, and may, under certain circumstances, be used to save allocation costs *

* * Suppose l is a List known to contain only strings. The following code can be used to dump the list into a newly allocated array of * String: * *

	 * 
	 * String[] x = (String[])v.toArray(new String[0]);
	 * 
*

* * Note that toArray(new Object[0]) is identical in function to toArray(). * * @param a the array into which the elements of this collection are to be stored, if it is big enough; otherwise, a new array of the same runtime type is * allocated for this purpose. * @return an array containing the elements of this collection * * @throws ArrayStoreException the runtime type of the specified array is not a supertype of the runtime type of every element in this collection. * @throws NullPointerException if the specified array is null. */ public T[] toArray(T[] a) { return list.toArray(a); } // Modification Operations /** * Ensures that this collection contains the specified element (optional operation). Returns true if this collection changed as a result of the call. * (Returns false if this collection does not permit duplicates and already contains the specified element.) *

* * Collections that support this operation may place limitations on what elements may be added to this collection. In particular, some collections will refuse * to add null elements, and others will impose restrictions on the type of elements that may be added. Collection classes should clearly specify in * their documentation any restrictions on what elements may be added. *

* * If a collection refuses to add a particular element for any reason other than that it already contains the element, it must throw an exception * (rather than returning false). This preserves the invariant that a collection always contains the specified element after this call returns. * * @param o element whose presence in this collection is to be ensured. * @return true if this collection changed as a result of the call * * @throws UnsupportedOperationException add is not supported by this collection. * @throws ClassCastException class of the specified element prevents it from being added to this collection. * @throws NullPointerException if the specified element is null and this collection does not support null elements. * @throws IllegalArgumentException some aspect of this element prevents it from being added to this collection. */ public boolean add(E o) { final int index = list.size(); //find out where the item will go final boolean changed = list.add(o); if(changed) { //if the list changed fireIntervalAdded(this, index, index); } return changed; } /** * Removes a single instance of the specified element from this collection, if it is present (optional operation). More formally, removes an element * e such that (o==null ? e==null : * o.equals(e)), if this collection contains one or more such elements. Returns true if this collection contained the specified element (or equivalently, * if this collection changed as a result of the call). * * @param o element to be removed from this collection, if present. * @return true if this collection changed as a result of the call * * @throws ClassCastException if the type of the specified element is incompatible with this collection (optional). * @throws NullPointerException if the specified element is null and this collection does not support null elements (optional). * @throws UnsupportedOperationException remove is not supported by this collection. */ public boolean remove(Object o) { final int index = list.indexOf(o); final boolean changed = list.remove(o); if(changed) { //if the list changed fireIntervalRemoved(this, index, index); } return changed; } // Bulk Operations /** * Returns true if this collection contains all of the elements in the specified collection. * * @param c collection to be checked for containment in this collection. * @return true if this collection contains all of the elements in the specified collection * @throws ClassCastException if the types of one or more elements in the specified collection are incompatible with this collection (optional). * @throws NullPointerException if the specified collection contains one or more null elements and this collection does not support null elements (optional). * @throws NullPointerException if the specified collection is null. * @see #contains(Object) */ public boolean containsAll(Collection c) { return list.containsAll(c); } /** * Adds all of the elements in the specified collection to this collection (optional operation). The behavior of this operation is undefined if the specified * collection is modified while the operation is in progress. (This implies that the behavior of this call is undefined if the specified collection is this * collection, and this collection is nonempty.) * * @param c elements to be inserted into this collection. * @return true if this collection changed as a result of the call * * @throws UnsupportedOperationException if this collection does not support the addAll method. * @throws ClassCastException if the class of an element of the specified collection prevents it from being added to this collection. * @throws NullPointerException if the specified collection contains one or more null elements and this collection does not support null elements, or if the * specified collection is null. * @throws IllegalArgumentException some aspect of an element of the specified collection prevents it from being added to this collection. * @see #add(Object) */ public boolean addAll(Collection c) { final int index = list.size(); final boolean changed = list.addAll(c); if(changed) { //if the list changed fireIntervalAdded(this, index, index + c.size() - 1); } return changed; } /** * * Removes all this collection's elements that are also contained in the specified collection (optional operation). After this call returns, this collection * will contain no elements in common with the specified collection. * * @param c elements to be removed from this collection. * @return true if this collection changed as a result of the call * * @throws UnsupportedOperationException if the removeAll method is not supported by this collection. * @throws ClassCastException if the types of one or more elements in this collection are incompatible with the specified collection (optional). * @throws NullPointerException if this collection contains one or more null elements and the specified collection does not support null elements (optional). * @throws NullPointerException if the specified collection is null. * @see #remove(Object) * @see #contains(Object) */ public boolean removeAll(Collection c) { final int oldSize = list.size(); //see how big the list was to begin with final boolean changed = list.removeAll(c); if(changed) { //if the list changed fireIntervalRemoved(this, list.size(), oldSize - 1); //there's no way to tell which ones changed--assume the last ones were removed fireContentsChanged(this, 0, list.size() - 1); //assume the first ones changed } return changed; } /** * Retains only the elements in this collection that are contained in the specified collection (optional operation). In other words, removes from this * collection all of its elements that are not contained in the specified collection. * * @param c elements to be retained in this collection. * @return true if this collection changed as a result of the call * * @throws UnsupportedOperationException if the retainAll method is not supported by this Collection. * @throws ClassCastException if the types of one or more elements in this collection are incompatible with the specified collection (optional). * @throws NullPointerException if this collection contains one or more null elements and the specified collection does not support null elements (optional). * @throws NullPointerException if the specified collection is null. * @see #remove(Object) * @see #contains(Object) */ public boolean retainAll(Collection c) { final int oldSize = list.size(); //see how big the list was to begin with final boolean changed = list.retainAll(c); if(changed) { //if the list changed fireIntervalRemoved(this, list.size(), oldSize - 1); //there's no way to tell which ones changed--assume the last ones were removed fireContentsChanged(this, 0, list.size() - 1); //assume the first ones changed } return changed; } /** * Removes all of the elements from this collection (optional operation). This collection will be empty after this method returns unless it throws an * exception. * * @throws UnsupportedOperationException if the clear method is not supported by this collection. */ public void clear() { final int oldSize = list.size(); list.clear(); if(oldSize > 0) //if anything was removed fireIntervalRemoved(this, 0, oldSize - 1); //show that everything was removed } // Comparison and hashing /** * Compares the specified object with this collection for equality. *

* * While the Collection interface adds no stipulations to the general contract for the Object.equals, programmers who implement the * Collection interface "directly" (in other words, create a class that is a Collection but is not a Set or a List) must * exercise care if they choose to override the Object.equals. It is not necessary to do so, and the simplest course of action is to rely on * Object's implementation, but the implementer may wish to implement a "value comparison" in place of the default "reference comparison." (The * List and Set interfaces mandate such value comparisons.) *

* * The general contract for the Object.equals method states that equals must be symmetric (in other words, a.equals(b) if and only if * b.equals(a)). The contracts for List.equals and Set.equals state that lists are only equal to other lists, and sets to other * sets. Thus, a custom equals method for a collection class that implements neither the List nor Set interface must return * false when this collection is compared to any list or set. (By the same logic, it is not possible to write a class that correctly implements both * the Set and List interfaces.) * * @param o Object to be compared for equality with this collection. * @return true if the specified object is equal to this collection * * @see Object#equals(Object) * @see Set#equals(Object) * @see List#equals(Object) */ public boolean equals(Object o) { return list.equals(o); } /** * Returns the hash code value for this collection. While the Collection interface adds no stipulations to the general contract for the * Object.hashCode method, programmers should take note that any class that overrides the Object.equals method must also override the * Object.hashCode method in order to satisfy the general contract for the Object.hashCodemethod. In particular, c1.equals(c2) * implies that c1.hashCode()==c2.hashCode(). * * @return the hash code value for this collection * * @see Object#hashCode() * @see Object#equals(Object) */ public int hashCode() { return list.hashCode(); } // Bulk Modification Operations /** * Inserts all of the elements in the specified collection into this list at the specified position (optional operation). Shifts the element currently at that * position (if any) and any subsequent elements to the right (increases their indices). The new elements will appear in this list in the order that they are * returned by the specified collection's iterator. The behavior of this operation is unspecified if the specified collection is modified while the operation * is in progress. (Note that this will occur if the specified collection is this list, and it's nonempty.) * * @param index index at which to insert first element from the specified collection. * @param c elements to be inserted into this list. * @return true if this list changed as a result of the call. * * @throws UnsupportedOperationException if the addAll method is not supported by this list. * @throws ClassCastException if the class of one of elements of the specified collection prevents it from being added to this list. * @throws NullPointerException if the specified collection contains one or more null elements and this list does not support null elements, or if the * specified collection is null. * @throws IllegalArgumentException if some aspect of one of elements of the specified collection prevents it from being added to this list. * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index > size()). */ public boolean addAll(int index, Collection c) { final boolean changed = list.addAll(index, c); if(changed) { //if the list changed fireIntervalAdded(this, index, index + c.size() - 1); } return changed; } // Positional Access Operations /** * Returns the element at the specified position in this list. * * @param index index of element to return. * @return the element at the specified position in this list. * * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= size()). */ public E get(int index) { return list.get(index); } /** * Replaces the element at the specified position in this list with the specified element (optional operation). * * @param index index of element to replace. * @param element element to be stored at the specified position. * @return the element previously at the specified position. * * @throws UnsupportedOperationException if the set method is not supported by this list. * @throws ClassCastException if the class of the specified element prevents it from being added to this list. * @throws NullPointerException if the specified element is null and this list does not support null elements. * @throws IllegalArgumentException if some aspect of the specified element prevents it from being added to this list. * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= size()). */ public E set(int index, E element) { final E oldObject = list.set(index, element); fireContentsChanged(this, index, index); return oldObject; } /** * Inserts the specified element at the specified position in this list (optional operation). Shifts the element currently at that position (if any) and any * subsequent elements to the right (adds one to their indices). * * @param index index at which the specified element is to be inserted. * @param element element to be inserted. * * @throws UnsupportedOperationException if the add method is not supported by this list. * @throws ClassCastException if the class of the specified element prevents it from being added to this list. * @throws NullPointerException if the specified element is null and this list does not support null elements. * @throws IllegalArgumentException if some aspect of the specified element prevents it from being added to this list. * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index > size()). */ public void add(int index, E element) { list.add(index, element); fireIntervalAdded(this, index, index); } /** * Removes the element at the specified position in this list (optional operation). Shifts any subsequent elements to the left (subtracts one from their * indices). Returns the element that was removed from the list. * * @param index the index of the element to removed. * @return the element previously at the specified position. * * @throws UnsupportedOperationException if the remove method is not supported by this list. * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index >= size()). */ public E remove(int index) { final E oldObject = list.remove(index); fireIntervalRemoved(this, index, index); return oldObject; } // Search Operations /** * Returns the index in this list of the first occurrence of the specified element, or -1 if this list does not contain this element. More formally, returns * the lowest index i such that (o==null ? get(i)==null : o.equals(get(i))), or -1 if there is no such index. * * @param o element to search for. * @return the index in this list of the first occurrence of the specified element, or -1 if this list does not contain this element. * @throws ClassCastException if the type of the specified element is incompatible with this list (optional). * @throws NullPointerException if the specified element is null and this list does not support null elements (optional). */ public int indexOf(Object o) { return list.indexOf(o); } /** * Returns the index in this list of the last occurrence of the specified element, or -1 if this list does not contain this element. More formally, returns * the highest index i such that (o==null ? get(i)==null : o.equals(get(i))), or -1 if there is no such index. * * @param o element to search for. * @return the index in this list of the last occurrence of the specified element, or -1 if this list does not contain this element. * @throws ClassCastException if the type of the specified element is incompatible with this list (optional). * @throws NullPointerException if the specified element is null and this list does not support null elements (optional). */ public int lastIndexOf(Object o) { return list.lastIndexOf(o); } // List Iterators /** * Returns a list iterator of the elements in this list (in proper sequence). * * @return a list iterator of the elements in this list (in proper sequence). */ public ListIterator listIterator() { return list.listIterator(); } /** * Returns a list iterator of the elements in this list (in proper sequence), starting at the specified position in this list. The specified index indicates * the first element that would be returned by an initial call to the next method. An initial call to the previous method would return the * element with the specified index minus one. * * @param index index of first element to be returned from the list iterator (by a call to the next method). * @return a list iterator of the elements in this list (in proper sequence), starting at the specified position in this list. * @throws IndexOutOfBoundsException if the index is out of range (index < 0 || index > size()). */ public ListIterator listIterator(int index) { return list.listIterator(index); } // View /** * Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive. (If fromIndex and * toIndex are equal, the returned list is empty.) The returned list is backed by this list, so non-structural changes in the returned list are * reflected in this list, and vice-versa. The returned list supports all of the optional list operations supported by this list. *

* * This method eliminates the need for explicit range operations (of the sort that commonly exist for arrays). Any operation that expects a list can be used * as a range operation by passing a subList view instead of a whole list. For example, the following idiom removes a range of elements from a list: * *

	 * list.subList(from, to).clear();
	 * 
* * Similar idioms may be constructed for indexOf and lastIndexOf, and all of the algorithms in the Collections class can be applied * to a subList. *

* * The semantics of the list returned by this method become undefined if the backing list (i.e., this list) is structurally modified in any way other * than via the returned list. (Structural modifications are those that change the size of this list, or otherwise perturb it in such a fashion that * iterations in progress may yield incorrect results.) * * @param fromIndex low endpoint (inclusive) of the subList. * @param toIndex high endpoint (exclusive) of the subList. * @return a view of the specified range within this list. * * @throws IndexOutOfBoundsException for an illegal endpoint index value (fromIndex < 0 || toIndex > size || fromIndex > toIndex). */ public List subList(int fromIndex, int toIndex) { return list.subList(fromIndex, toIndex); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy