An extension of Vector that provides some handy utilities for working with JavaBeans : Java Beans « Development Class « Java

Home
Java
1.2D Graphics GUI
2.3D
3.Advanced Graphics
4.Ant
5.Apache Common
6.Chart
7.Class
8.Collections Data Structure
9.Data Type
10.Database SQL JDBC
11.Design Pattern
12.Development Class
13.EJB3
14.Email
15.Event
16.File Input Output
17.Game
18.Generics
19.GWT
20.Hibernate
21.I18N
22.J2EE
23.J2ME
24.JavaFX
25.JDK 6
26.JDK 7
27.JNDI LDAP
28.JPA
29.JSP
30.JSTL
31.Language Basics
32.Network Protocol
33.PDF RTF
34.Reflection
35.Regular Expressions
36.Scripting
37.Security
38.Servlets
39.Spring
40.Swing Components
41.Swing JFC
42.SWT JFace Eclipse
43.Threads
44.Tiny Application
45.Velocity
46.Web Services SOA
47.XML
Java » Development Class » Java Beans 




An extension of Vector that provides some handy utilities for working with JavaBeans
    
/*
 * BeanVector.java
 *
 * Created on May 21, 2004, 7:23 PM
 *
 * Copyright (C) 2004, 2005  Robert Cooper, Temple of the Screaming Penguin
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyDescriptor;

import java.lang.Comparable;
import java.lang.reflect.*;

import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.Vector;


/** This is an extension of Vector that provides some handy utilities for working with JavaBeans.
 * Includes basic statistical information, page chunking and storing and can also be used as a manager for
 * indexed properies and supports PropertyChangeEvents.
 *
 @version $Rev: 79 $
 @author  <a href="cooper@screaming-penguin.com">Robert Cooper</a>
 */
public class BeanVector<T> extends Vector<T> {
    /**
     * DOCUMENT ME!
     */
    Collection source;

    /**
     * DOCUMENT ME!
     */
    private PropertyChangeSupport changes;

    /**
     * DOCUMENT ME!
     */
    private String indexPropertyName;

    /**
     * DOCUMENT ME!
     */
    private int nextChunk = -1;

    /**
     * DOCUMENT ME!
     */
    private int numberOfChunks = 1;

    /**
     * DOCUMENT ME!
     */
    private int previousChunk = -1;

    /** No Args Contstructor */
    public BeanVector() {
        super();
    }

    /**
     * This contructs a new BeanVector with PropertyChangeEvent support.
     @param indexPropertyName the property name of the parent object to fire events for
     @param changeOwner the owner object that change events should "come from"
     */
    public BeanVector(String indexPropertyName,Object changeOwner) {
        this();
        this.indexPropertyName = indexPropertyName;
        this.changes = new PropertyChangeSupport(changeOwner);
    }

    /**
     * Creates a new instance of BeanVector prepopulating off a
     * collection, limited to only the desired chunk.
     @param source Collection to read from
     @param chunkSize int number of object to return.
     @param currentChunk int value of the chunk to get (zero index)
     */
    public BeanVector(int chunkSize,int currentChunk,Collection<T> source) {
        super();
        this.source = source;

        Iterator<T> itr = source.iterator();

        if(source.size() 0) {
            this.numberOfChunks = source.size() / chunkSize;

            if((source.size() % chunkSize0) {
                this.numberOfChunks++;
            }

            //spin
            for(int i = 0; i < (chunkSize * currentChunk); i++) {
                if(!itr.hasNext()) {
                    continue;
                }

                itr.next();
            }

            for(int i = 0; i < chunkSize; i++) {
                if(!itr.hasNext()) {
                    continue;
                }

                this.add(itr.next());
            }

            if(currentChunk != 0) {
                previousChunk = currentChunk - 1;
            }

            if(source.size() ((currentChunk + 1* chunkSize)) {
                nextChunk = currentChunk + 1;
            }
        }
    }

    /**
     * Creates a new instance of BeanVector prepopulating off a
     * collection, limited to only the desired chunk, and includes
     * PropertyChangeEvent support.
     @param indexPropertyName the property name of the parent object to fire events for
     @param changeOwner the object change events should come from
     @param chunkSize number of objects to return
     @param currentChunk int value of the chunk to get (zero index)
     @param source source Collection to read from.
     */
    public BeanVector(String indexPropertyName,Object changeOwner,int chunkSize,int currentChunk,Collection<T> source) {
        this(chunkSize,currentChunk,source);
        this.indexPropertyName = indexPropertyName;
        this.changes = new PropertyChangeSupport(changeOwner);
    }

    /** Creates a new instance of BeanVector
     @param source Collection containing the initial values.
     */
    public BeanVector(Collection<T> source) {
        this(source.size(),0,source);
    }

    /**
     * This contructs a new BeanVector with PropertyChangeEvent support.
     @param indexPropertyName the property name of the parent object to fire events for
     @param changeOwner the object change events should come from
     @param source Collection to prepopulate from.
     */
    public BeanVector(String indexPropertyName,Object changeOwner,Collection<T> source) {
        this(source);
        this.indexPropertyName = indexPropertyName;
        this.changes = new PropertyChangeSupport(changeOwner);
    }

    /**
     * Gets a chunk of this vector.
     @param chunkSize int number of object to return.
     @param currentChunk int value of the chunk to get (zero index)
     @return new BeanVector representing the chunk requested.
     */
    public BeanVector getChunk(int chunkSize,int currentChunk) {
        return new BeanVector(chunkSize,currentChunk,this);
    }

    /**
     * Overrides the parent to support PropertyChangeEvents
     @param obj new object value
     @param index index position to place the object
     */
    public void setElementAt(T obj,int index) {
        T old = null;

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            old = this.elementAt(index);
        }

        super.setElementAt(obj,index);

        if(old != null) {
            changes.fireIndexedPropertyChange(this.indexPropertyName,index,old,obj);
        }
    }

    /**
     * Filters a property using the Comparable.compareTo() on the porperty to
     * test for a range
     @param propertyName property to filter on
     @param inclusive include the values of the range limiters
     @param fromValue low range value
     @param toValue high range value
     @throws java.lang.IllegalAccessException reflection exception
     @throws java.beans.IntrospectionException reflection exception
     @throws java.lang.reflect.InvocationTargetException reflection exception
     @return new BeanVector filtered on the range
     */
    public BeanVector<T> getFiltered(String propertyName,boolean inclusive,Comparable fromValue,Comparable toValuethrows java.lang.IllegalAccessException,java.beans.IntrospectionException,java.lang.reflect.InvocationTargetException {
        Hashtable cache = new Hashtable();
        String currentClass = "";
        PropertyDescriptor pd = null;
        BeanVector<T> results = new BeanVector<T>();

        for(int i = 0; i < this.size(); i++) {
            T o = this.elementAt(i);

            if(!currentClass.equals(o.getClass().getName())) {
                pd = (PropertyDescriptor)cache.get(o.getClass().getName());

                if(pd == null) {
                    PropertyDescriptor[] pds = Introspector.getBeanInfo(o.getClass()).getPropertyDescriptors();
                    boolean foundProperty = false;

                    for(int pdi = 0(pdi < pds.length)&&!foundProperty;
                            pdi++) {
                        if(pds[pdi].getName().equals(propertyName)) {
                            pd = pds[pdi];
                            cache.put(o.getClass().getName(),pd);
                            foundProperty = true;
                        }
                    }
                }
            }

            Comparable value = (Comparable)pd.getReadMethod().invoke(o);

            if((value.compareTo(fromValue0)&&(value.compareTo(toValue0)) {
                results.add(o);
            else if(inclusive&&((value.compareTo(fromValue== 0)||(value.compareTo(toValue== 0))) {
                results.add(o);
            }
        }

        return results;
    }

    /**
     * This method does a string match on values of a property.
     @param propertyName String value containing the name of the property to match.
     @param match Value to search for. This is a case-insensitive value that takes % as a multiple character wildcard value.
     @throws java.lang.IllegalAccessException reflection exception
     @throws java.beans.IntrospectionException reflection exception
     @throws java.lang.reflect.InvocationTargetException reflection exception
     @return a new BeanVector filtered on the specified property
     */
    public BeanVector<T> getFilteredStringMatch(String propertyName,String matchthrows java.lang.IllegalAccessException,java.beans.IntrospectionException,java.lang.reflect.InvocationTargetException {
        Hashtable cache = new Hashtable();
        String currentClass = "";
        PropertyDescriptor pd = null;
        BeanVector<T> results = new BeanVector<T>();

        for(int i = 0; i < this.size(); i++) {
            T o = this.elementAt(i);

            if(!currentClass.equals(o.getClass().getName())) {
                pd = (PropertyDescriptor)cache.get(o.getClass().getName());

                if(pd == null) {
                    PropertyDescriptor[] pds = Introspector.getBeanInfo(o.getClass()).getPropertyDescriptors();
                    boolean foundProperty = false;

                    for(int pdi = 0(pdi < pds.length)&&!foundProperty;
                            pdi++) {
                        if(pds[pdi].getName().equals(propertyName)) {
                            pd = pds[pdi];
                            cache.put(o.getClass().getName(),pd);
                            foundProperty = true;
                        }
                    }
                }
            }

            String value = pd.getReadMethod().invoke(o).toString().toLowerCase();
            StringTokenizer st = new StringTokenizer(match.toLowerCase(),"%");
            boolean isMatch = true;
            int matchIndex = 0;

            while(st.hasMoreTokens()&&isMatch) {
                String tk = st.nextToken();

                if(value.indexOf(tk,matchIndex== -1) {
                    isMatch = false;
                else {
                    matchIndex = value.indexOf(tk,matchIndex+ tk.length();
                }
            }

            if(isMatch) {
                results.add(o);
            }
        }

        return results;
    }

    /**
     * This method returns the average value of a numerical property.
     @param propertyName String value of the property name to calculate.
     @throws java.lang.IllegalAccessException reflection exception
     @throws java.beans.IntrospectionException reflection exception
     @throws java.lang.reflect.InvocationTargetException reflection exception
     @return Average of property values.
     */
    public Number getMeanOfProperty(String propertyNamethrows java.lang.IllegalAccessException,java.beans.IntrospectionException,java.lang.reflect.InvocationTargetException {
        double mean = this.getSumOfProperty(propertyName).doubleValue() this.size();

        return new Double(mean);
    }

    /**
     * This method returns the index of the bean with the median value
     * on the specified property.
     *
     * <p>If there is an odd number of items in the dataset, the one below
     * the 50% mark will be returned. The true mathmatical mean, therefore
     * would be:
     * <code>
     * (beanVector.elementAt(x).getProperty() + beanVector.elementAt(x+1).getProperty() )/2
     * </code></p>
     @param propertyName String value of the property name to calculate.
     @throws java.lang.IllegalAccessException reflection exception
     @throws java.beans.IntrospectionException reflection exception
     @throws java.lang.reflect.InvocationTargetException reflection exception
     @return int value of the median index of the Vector
     */
    public int getMedianIndex(String propertyNamethrows java.lang.IllegalAccessException,java.beans.IntrospectionException,java.lang.reflect.InvocationTargetException {
        BeanVector bv = new BeanVector(this.size(),0,this);
        bv.sortOnProperty(propertyName);

        int orderedIndex = bv.size() 2;
        Object o = bv.elementAt(orderedIndex);

        return this.indexOf(o);
    }

    /**
     * This method returns the index of an object representing the
     * mode value of a property name.
     @param propertyName String value of the property name to calculate.
     @throws java.lang.IllegalAccessException reflection exception
     @throws java.beans.IntrospectionException reflection exception
     @throws java.lang.reflect.InvocationTargetException reflection exception
     @return int value of the mode index
     */
    public int getModeIndex(String propertyNamethrows java.lang.IllegalAccessException,java.beans.IntrospectionException,java.lang.reflect.InvocationTargetException {
        int index = -1;
        int max = 0;
        int count = 0;
        Object o = null;
        Object hold = null;
        Hashtable cache = new Hashtable();
        String currentClass = "";
        PropertyDescriptor pd = null;
        BeanVector bv = new BeanVector(this.size(),0,this);
        bv.sortOnProperty(propertyName);

        for(int i = 0; i < bv.size(); i++) {
            if(!currentClass.equals(bv.elementAt(i).getClass().getName())) {
                pd = (PropertyDescriptor)cache.get(bv.elementAt(i).getClass().getName());

                if(pd == null) {
                    PropertyDescriptor[] pds = Introspector.getBeanInfo(bv.elementAt(i).getClass()).getPropertyDescriptors();
                    boolean foundProperty = false;

                    for(int pdi = 0(pdi < pds.length)&&!foundProperty;
                            pdi++) {
                        if(pds[pdi].getName().equals(propertyName)) {
                            pd = pds[pdi];
                            cache.put(bv.elementAt(i).getClass().getName(),pd);
                            foundProperty = true;
                        }
                    }
                }
            }

            if(hold == null) {
                hold = pd.getReadMethod().invoke(bv.elementAt(i));
            else {
                o = pd.getReadMethod().invoke(bv.elementAt(i));

                if((o != null)&&o.equals(hold)) {
                    count++;

                    if(count > max) {
                        max = count;
                        index = this.indexOf(bv.elementAt(i));
                    }
                else {
                    count = 1;
                }

                hold = o;
            }
        }

        return index;
    }

    /** Returns -1 or the the index of the next chunk after the current
     * vector.
     @return -1 or the the index of the next chunk after the current vector
     */
    public int getNextChunk() {
        return this.nextChunk;
    }

    /**
     * returns the number of chunks in the vector
     @return int value number of chunks
     */
    public int getNumberOfChunks() {
        return this.numberOfChunks;
    }

    /** Returns -1 or the the index of the previous chunk before the
     * current vector.
     @return -1 or the the index of the previous chunk before the
     * current vector
     */
    public int getPreviousChunk() {
        return this.previousChunk;
    }

    /**
     * This method returns the sum of all values of a numerical
     * property.
     @param propertyName String value of the property name to calculate.
     @throws java.lang.IllegalAccessException reflection exception
     @throws java.beans.IntrospectionException reflection exception
     @throws java.lang.reflect.InvocationTargetException reflection exception
     @return sum of a numerical property
     */
    public Number getSumOfProperty(String propertyNamethrows java.lang.IllegalAccessException,java.beans.IntrospectionException,java.lang.reflect.InvocationTargetException {
        double d = 0.0;
        String currentClass = "";
        PropertyDescriptor pd = null;

        for(int i = 0; i < this.size(); i++) {
            T o = this.elementAt(i);

            if(!currentClass.equals(o.getClass().getName())) {
                PropertyDescriptor[] pds = Introspector.getBeanInfo(o.getClass()).getPropertyDescriptors();
                boolean foundProperty = false;

                for(int pdi = 0(pdi < pds.length)&&!foundProperty; pdi++) {
                    if(pds[pdi].getName().equals(propertyName)) {
                        pd = pds[pdi];
                        foundProperty = true;
                    }
                }
            }

            if(o != null) {
                Number n = (Number)pd.getReadMethod().invoke(o);
                d += n.doubleValue();
            }
        }

        return new Double(d);
    }

    /**
     * Inserts the specified element at the specified position in this Vector.
     * Shifts the element currently at that position (if any) and any
     * subsequent elements to the right (adds one to their indices).
     *
     @since 1.2
     @param index index at which the specified element is to be inserted.
     @param element element to be inserted.
     */
    public void add(int index,T element) {
        T[] old = null;

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            old = this.toTypedArray();
        }

        super.add(index,element);

        if(old != null) {
            changes.firePropertyChange(this.indexPropertyName,old,this.toTypedArray());
        }
    }

    /**
     * Appends the specified element to the end of this Vector.
     *
     @param o element to be appended to this Vector.
     @return true (as per the general contract of Collection.add).
     @since 1.2
     */
    public boolean add(T o) {
        boolean retValue;
        retValue = super.add(o);

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            changes.fireIndexedPropertyChange(this.indexPropertyName,this.size() 1,null,o);
        }

        return retValue;
    }

    /**
     * Appends all of the elements in the specified Collection to the end of
     * this Vector, in the order that they are returned by the specified
     * Collection's Iterator.  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 Vector, and this Vector is nonempty.)
     *
     @return <tt>true</tt> if this Vector changed as a result of the call.
     @since 1.2
     @param c elements to be inserted into this Vector.
     */
    public boolean addAll(Collection<? extends T> c) {
        boolean retValue;
        T[] old = null;

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            old = this.toTypedArray();
        }

        retValue = super.addAll(c);

        if(retValue&&(old != null)) {
            changes.firePropertyChange(this.indexPropertyName,old,this.toTypedArray());
        }

        return retValue;
    }

    /**
     * Inserts all of the elements in the specified Collection into this
     * Vector at the specified position.  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 the Vector
     * in the order that they are returned by the specified Collection's
     * iterator.
     *
     @return <tt>true</tt> if this Vector changed as a result of the call.
     @since 1.2
     @param index index at which to insert first element
     *                     from the specified collection.
     @param c elements to be inserted into this Vector.
     */
    public boolean addAll(int index,Collection<? extends T> c) {
        boolean retValue;
        T[] old = null;

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            old = this.toTypedArray();
        }

        retValue = super.addAll(index,c);

        if(retValue&&(old != null)) {
            changes.firePropertyChange(this.indexPropertyName,old,this.toTypedArray());
        }

        return retValue;
    }

    /**
     * Adds the specified component to the end of this vector,
     * increasing its size by one. The capacity of this vector is
     * increased if its size becomes greater than its capacity. <p>
     *
     * This method is identical in functionality to the add(Object) method
     * (which is part of the List interface).
     *
     @param   obj   the component to be added.
     @see           #add(Object)
     @see           List
     */
    public void addElement(T obj) {
        super.addElement(obj);

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            changes.fireIndexedPropertyChange(this.indexPropertyName,this.size() 1,null,obj);
        }
    }

    /**
     * Registers propertyChangeListeners to be fired when something changes in the Vector.
     * Note, the whole vector is an "indexedProperty" name specified and parent delineated in
     * the constructor.
     @param listener PropertyChangeListener to register
     */
    public void addPropertyChangeListener(PropertyChangeListener listener) {
        changes.addPropertyChangeListener(listener);
    }

    /**
     * Registers propertyChangeListeners to be fired when something changes in the Vector.
     * Note, the whole vector is an "indexedProperty" name specified and parent delineated in
     * the constructor.
     @param property propteryName must match what the property name of this vector is or the listener will be ignored.
     @param listener the listener to register
     */
    public void addPropertyChangeListener(String property,PropertyChangeListener listener) {
        if((property != null)&&property.equals(this.indexPropertyName)) {
            changes.addPropertyChangeListener(property,listener);
        }
    }

    /**
     * This method reverses the order of the vector.
     */
    public synchronized void invert() {
        BeanVector<T> temp = new BeanVector<T>(this);

        for(int i = 0; i < this.size(); i++) {
            this.setElementAt(temp.lastElement(),i);
            temp.remove(temp.lastElement());
        }
    }

    /**
     * Removes the first occurrence of the specified element in this Vector
     * If the Vector does not contain the element, it is unchanged.  More
     * formally, removes the element with the lowest index i such that
     * <code>(o==null ? get(i)==null : o.equals(get(i)))</code> (if such
     * an element exists).
     *
     @param o element to be removed from this Vector, if present.
     @return true if the Vector contained the specified element.
     @since 1.2
     */
    public boolean remove(Object o) {
        boolean retValue;
        T[] old = null;

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            old = this.toTypedArray();
        }

        retValue = super.remove(o);

        if(retValue&&(old != null)) {
            changes.firePropertyChange(this.indexPropertyName,old,this.toTypedArray());
        }

        return retValue;
    }

    /**
     * Removes the element at the specified position in this Vector.
     * shifts any subsequent elements to the left (subtracts one from their
     * indices).  Returns the element that was removed from the Vector.
     *
     @return element that was removed
     @since 1.2
     @param index the index of the element to removed.
     */
    public T remove(int index) {
        T retValue;
        T[] old = null;

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            old = this.toTypedArray();
        }

        retValue = super.remove(index);

        if((retValue != null)&&(old != null)) {
            changes.firePropertyChange(this.indexPropertyName,old,this.toTypedArray());
        }

        return retValue;
    }

    /**
     * Removes from this Vector all of its elements that are contained in the
     * specified Collection.
     *
     @return true if this Vector changed as a result of the call.
     @since 1.2
     @param c a collection of elements to be removed from the Vector
     */
    public boolean removeAll(Collection<? > c) {
        boolean retValue;
        T[] old = null;

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            old = this.toTypedArray();
        }

        retValue = super.removeAll(c);

        if(retValue&&(old != null)) {
            changes.firePropertyChange(this.indexPropertyName,old,this.toTypedArray());
        }

        return retValue;
    }

    /**
     * Removes all components from this vector and sets its size to zero.<p>
     *
     * This method is identical in functionality to the clear method
     * (which is part of the List interface).
     *
     @see        #clear
     @see        List
     */
    public void removeAllElements() {
        T[] old = null;

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            old = this.toTypedArray();
        }

        super.removeAllElements();

        if(old != null) {
            changes.firePropertyChange(this.indexPropertyName,old,this.toTypedArray());
        }
    }

    /**
     * Removes the first (lowest-indexed) occurrence of the argument
     * from this vector. If the object is found in this vector, each
     * component in the vector with an index greater or equal to the
     * object's index is shifted downward to have an index one smaller
     * than the value it had previously.<p>
     *
     * This method is identical in functionality to the remove(Object)
     * method (which is part of the List interface).
     *
     @param   obj   the component to be removed.
     @return  <code>true</code> if the argument was a component of this
     *          vector; <code>false</code> otherwise.
     @see        List#remove(Object)
     @see        List
     */
    public boolean removeElement(Object obj) {
        boolean retValue;
        T[] old = null;

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            old = this.toTypedArray();
        }

        retValue = super.removeElement(obj);

        if(retValue&&(old != null)) {
            changes.firePropertyChange(this.indexPropertyName,old,this.toTypedArray());
        }

        return retValue;
    }

    /**
     * Deletes the component at the specified index. Each component in
     * this vector with an index greater or equal to the specified
     * <code>index</code> is shifted downward to have an index one
     * smaller than the value it had previously. The size of this vector
     * is decreased by <tt>1</tt>.<p>
     *
     * The index must be a value greater than or equal to <code>0</code>
     * and less than the current size of the vector. <p>
     *
     * This method is identical in functionality to the remove method
     * (which is part of the List interface).  Note that the remove method
     * returns the old value that was stored at the specified position.
     *
     @see #size()
     @see #remove(int)
     @see List
     @param index the index of the object to remove.
     */
    public void removeElementAt(int index) {
        T[] old = null;

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            old = this.toTypedArray();
        }

        super.removeElementAt(index);

        if(old != null) {
            changes.firePropertyChange(this.indexPropertyName,old,this.toTypedArray());
        }
    }

    /**
     * Removes propertyChangeListeners to be fired when something changes in the Vector.
     * Note, the whole vector is an "indexedProperty" name specified and parent delineated in
     * the constructor.
     @param listener listener to remove
     */
    public void removePropertyChangeListener(PropertyChangeListener listener) {
        changes.removePropertyChangeListener(listener);
    }

    /**
     * Removes propertyChangeListeners to be fired when something changes in the Vector.
     * Note, the whole vector is an "indexedProperty" name specified and parent delineated in
     * the constructor.
     @param property must match the current property name for the vector or will be ignored
     @param listener listener to remove
     */
    public void removePropertyChangeListener(String property,PropertyChangeListener listener) {
        if((property != null)&&property.equals(this.indexPropertyName)) {
            changes.removePropertyChangeListener(property,listener);
        }
    }

    /**
     * Resets the contents of the vector to the values provided.
     @param contents Array of object to replace the current contents with
     */
    public synchronized void resetContents(T[] contents) {
        if((this.indexPropertyName != null)&&(this.changes != null)) {
            changes.firePropertyChange(this.indexPropertyName,this.toTypedArray(),contents);
        }

        this.removeAllElements();

        for(T t : contents)
            this.add(t);
    }

    /**
     * Retains only the elements in this Vector that are contained in the
     * specified Collection.  In other words, removes from this Vector all
     * of its elements that are not contained in the specified Collection.
     *
     @return true if this Vector changed as a result of the call.
     @since 1.2
     @param c a collection of elements to be retained in this Vector
     *          (all other elements are removed)
     */
    public boolean retainAll(Collection<? > c) {
        boolean retValue;
        T[] old = null;

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            old = this.toTypedArray();
        }

        retValue = super.retainAll(c);

        if(retValue&&(old != null)) {
            changes.firePropertyChange(this.indexPropertyName,old,this.toTypedArray());
        }

        return retValue;
    }

    /**
     * Replaces the element at the specified position in this Vector with the
     * specified element.
     *
     @return the element previously at the specified position.
     @since 1.2
     @param index index of element to replace.
     @param element element to be stored at the specified position.
     */
    public T set(int index,T element) {
        T retValue;
        retValue = super.set(index,element);

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            changes.fireIndexedPropertyChange(this.indexPropertyName,index,retValue,element);
        }

        return retValue;
    }

    /**
     * performs a selection sort on all the beans in the Vector by PropertyName
     *
     * <p>You can use a mixture of bean classes as long as all the beans support
     * the same property (getName() for instance), and all have the same return
     * type.</p>
     *
     * <p>For optimal performance, it is recommended that if you have a
     * mixed class set the you have them grouped with like classes together as this
     * will minimize reflection inspections.</p>
     @param propertyName String value containing the property to sort
     * on.
     @throws java.lang.IllegalAccessException Property was not accessible
     @throws java.beans.IntrospectionException Couldn't introspect
     @throws java.lang.reflect.InvocationTargetException Is the proper signature getProperty() ?
     */
    public void sortOnProperty(String propertyNamethrows java.lang.IllegalAccessException,java.beans.IntrospectionException,java.lang.reflect.InvocationTargetException {
        this.sortOnProperty(propertyName,true);
    }

    /**
     * performs a selection sort on all the beans in the Vector by
     * PropertyName
     *
     * <p>You can use a mixture of bean classes as long as all the beans
     * support the same property (getName() for instance), and all have the
     * same return type, or can be compareTo()ed each other.</p>
     *
     * <p>For optimal performance, it is recommended that if you have a
     * mixed class set the you have them grouped with like classes together
     * as this will minimize reflection inspections.</p>
     @param propertyName String value containing the property to sort on.
     @param ascending == sorts up if true, down if not.
     @throws java.lang.IllegalAccessException reflection exception
     @throws java.beans.IntrospectionException reflection exception
     @throws java.lang.reflect.InvocationTargetException reflection exception
     */
    public synchronized void sortOnProperty(String propertyName,boolean ascendingthrows java.lang.IllegalAccessException,java.beans.IntrospectionException,java.lang.reflect.InvocationTargetException {
        T[] old = null;

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            old = this.toTypedArray();
        }

        T temp = null;
        String currentClass = "";
        PropertyDescriptor pd = null;
        Hashtable cache = new Hashtable();

        for(int i = 0; i < (this.size() 1); i++) {
            for(int j = i + 1; j < this.size(); j++) {
                T o1 = this.elementAt(i);

                if(!currentClass.equals(o1.getClass().getName())) {
                    pd = (PropertyDescriptor)cache.get(o1.getClass().getName());

                    if(pd == null) {
                        PropertyDescriptor[] pds = Introspector.getBeanInfo(o1.getClass()).getPropertyDescriptors();
                        boolean foundProperty = false;

                        for(int pdi = 0(pdi < pds.length)&&!foundProperty;
                                pdi++) {
                            if(pds[pdi].getName().equals(propertyName)) {
                                pd = pds[pdi];
                                cache.put(o1.getClass().getName(),pd);
                                foundProperty = true;
                            }
                        }
                    }
                }

                //System.out.println( "o1: "+o1+" "+pd);
                //System.out.println( propertyName +" "+ (pd == null ));
                Comparable oc1 = (Comparable)pd.getReadMethod().invoke(o1);

                T o2 = this.elementAt(j);

                if(!currentClass.equals(o2.getClass().getName())) {
                    pd = (PropertyDescriptor)cache.get(o2.getClass().getName());

                    if(pd == null) {
                        PropertyDescriptor[] pds = Introspector.getBeanInfo(o2.getClass()).getPropertyDescriptors();
                        boolean foundProperty = false;

                        for(int pdi = 0(pdi < pds.length)&&!foundProperty;
                                pdi++) {
                            if(pds[pdi].getName().equals(propertyName)) {
                                pd = pds[pdi];
                                foundProperty = true;
                            }
                        }
                    }
                }

                Comparable oc2 = (Comparable)pd.getReadMethod().invoke(o2);

                if(ascending) {
                    if((oc1 != oc2)&&((oc2 == null)||((oc1 != null)&&(oc2 != null)&&(oc2.compareTo(oc10)))) { //swap
                        this.setElementAt(o2,i);
                        this.setElementAt(o1,j);
                    }
                else {
                    if((oc1 != oc2)&&((oc1 == null)||((oc1 != null)&&(oc2 != null)&&(oc1.compareTo(oc20)))) { //swap
                        this.setElementAt(o2,i);
                        this.setElementAt(o1,j);
                    }
                }
            }

            if(old != null) {
                changes.firePropertyChange(this.indexPropertyName,old,this.toTypedArray());
            }
        }
    }

    /**
     * Returns an Array of the generic type associated with this Vector.
     @return Array representation of the current vector.
     */
    public T[] toTypedArray() {
        return (T[])this.toArray();
    }

    /**
     * Removes from this List all of the elements whose index is between
     * fromIndex, inclusive and toIndex, exclusive.  Shifts any succeeding
     * elements to the left (reduces their index).
     * This call shortens the ArrayList by (toIndex - fromIndex) elements.  (If
     * toIndex==fromIndex, this operation has no effect.)
     *
     @param fromIndex index of first element to be removed.
     @param toIndex index after last element to be removed.
     */
    protected void removeRange(int fromIndex,int toIndex) {
        T[] old = null;

        if((this.indexPropertyName != null)&&(this.changes != null)) {
            old = this.toTypedArray();
        }

        super.removeRange(fromIndex,toIndex);

        if(old != null) {
            changes.firePropertyChange(this.indexPropertyName,old,this.toTypedArray());
        }
    }
}

   
    
    
    
  














Related examples in the same category
1.JavaBean: BeanContextSupportJavaBean: BeanContextSupport
2.JavaBean: Test program that adds 100 beans to a contextJavaBean: Test program that adds 100 beans to a context
3.JavaBean: how to use the instantiateChild() convenience method to create a beanJavaBean: how to use the instantiateChild() convenience method to create a bean
4.JavaBean: illustrate delivery of the BeanContextMembershipEventJavaBean: illustrate delivery of the BeanContextMembershipEvent
5.JavaBean: creates all of the objects, a tests the service capabilitiesJavaBean: creates all of the objects, a tests the service capabilities
6.Bean ContainerBean Container
7.PropertyTablePropertyTable
8.Introspecting a BeanIntrospecting a Bean
9.Listening for Changes to the Selected File in a JFileChooser Dialog
10.Get a list of selected files
11.Listening for Changes to the Current Directory in a JFileChooser Dialog
12.Displaying the Current Directory in the Title of a JFileChooser Dialog
13.Setting an Accessory Component in a JFileChooser Dialog
14.Convert a bean to XML persistence
15.Listen for bean's property change event
16.List property names of a Bean
17.Prevent bean's property being serialized to XML
18.Create an instance a Bean
19.Convert an XML persistence to bean
20.Determine bean's property type
21.Listen for a constrained property change
22.Bean has a single property called property.
23.Implementing a Bound Property
24.Implementing a Constrained Property: fires a PropertyChangeEvent whenever its value is about to be changed.
25.Instantiating a Bean
26.Listing the Property Names of a Bean
27.Getting and Setting a Property of a Bean
28.Get and set the value of a property in a bean using Expression and Statement
29.Get and set an Object type property
30.gets and sets a primitive type property
31.gets and sets an array type property
32.Serializing a Bean to XML: XMLEncoder only persists the value of public properties.
33.Deserializing a Bean from XML
34.Preventing a Bean Property from Being Serialized to XML
35.Serializing an Immutable Bean Property to XML
36.Listening for a Property Change Event: A property change event is fired when a bound property is changed.
37.Listening for a Vetoable Property Change Event
38.Read bean's property value
39.Saving and restoring the state of a pretend CAD systemSaving and restoring the state of a pretend CAD system
40.An extension of ArrayList that provides some handy utilities for working with JavaBeans
41.extends SimpleBeanInfo
42.Get and set properties on a bean
43.Bean Utility
44.Is JavaBean Compliant Setter
45.This program demonstrates the use of an XML encoder and decoder to save and restore a frame.
46.This program demonstrates various persistence delegates.
47.Event Tracer
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.