Revision: 1302
Author:   mathiasbr
Date:     2006-08-16 08:18:25 -0700 (Wed, 16 Aug 2006)
ViewCVS:  http://svn.sourceforge.net/spring-rich-c/?rev=1302&view=rev

Log Message:
-----------
add a protected method to fetch the index for a filtered index
add tests to verify implementation of FilteredListModel
add javadoc to FilteredListModel

Modified Paths:
--------------
    
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/list/FilteredListModel.java

Added Paths:
-----------
    
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/list/FilteredListModelTests.java
Modified: 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/list/FilteredListModel.java
===================================================================
--- 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/list/FilteredListModel.java
    2006-08-16 15:18:17 UTC (rev 1301)
+++ 
trunk/spring-richclient/support/src/main/java/org/springframework/richclient/list/FilteredListModel.java
    2006-08-16 15:18:25 UTC (rev 1302)
@@ -22,32 +22,57 @@
 import javax.swing.event.ListDataEvent;
 
 import org.springframework.core.closure.Constraint;
+import org.springframework.util.Assert;
 
 /**
+ * Decorates an existing [EMAIL PROTECTED] ListModel} by applying a 
constraint. The constraint can implement [EMAIL PROTECTED] Observable} to
+ * notify a change of the filter condition.
+ * 
  * @author Keith Donald
+ * @author Mathias Broekelmann
  */
 public class FilteredListModel extends AbstractFilteredListModel implements 
Observer {
 
-    private Constraint constraint;
+    private final Constraint constraint;
 
     private int[] indexes;
 
     private int filteredSize;
 
+    /**
+     * Constructs a new instance
+     * 
+     * @param listModel
+     *            the list model to filter.
+     * @param constraint
+     *            the constraint which is applied to the list model elements
+     * 
+     * @throws IllegalArgumentException
+     *             if list model or constraint parameters where null
+     */
     public FilteredListModel(ListModel listModel, Constraint constraint) {
         super(listModel);
+        Assert.notNull(constraint);
         this.constraint = constraint;
         if (this.constraint instanceof Observable) {
-            ((Observable)this.constraint).addObserver(this);
+            ((Observable) this.constraint).addObserver(this);
         }
         reallocateIndexes();
     }
 
+    /**
+     * Internally called to reallocate the indexes. This method should be 
called when the filtered model changes its
+     * element size
+     */
     protected void reallocateIndexes() {
         this.indexes = new int[getFilteredModel().getSize()];
         applyConstraint();
     }
 
+    /**
+     * If the constraint implements [EMAIL PROTECTED] Observable} this method 
is called and will apply the constraint to the list
+     * model elements
+     */
     public void update(Observable changed, Object arg) {
         applyConstraint();
         fireContentsChanged(this, -1, -1);
@@ -56,34 +81,58 @@
     private void applyConstraint() {
         filteredSize = 0;
         ListModel filteredListModel = getFilteredModel();
-        for (int i = 0, j = 0; i < filteredListModel.getSize(); i++) {
+        for (int i = 0, size = filteredListModel.getSize(); i < size; i++) {
             Object element = filteredListModel.getElementAt(i);
             if (constraint.test(element)) {
-                indexes[j] = i;
-                j++;
-                filteredSize++;
+                indexes[filteredSize++] = i;
                 onMatchingElement(element);
             }
         }
         postConstraintApplied();
     }
 
+    /**
+     * Called to notify that an element has matched the filter constraint. 
This implementation does nothing.
+     * 
+     * @param element
+     *            the element which was accepted by the filter
+     */
     protected void onMatchingElement(Object element) {
 
     }
 
+    /**
+     * Called to notify that the constraint was applied to all elements. This 
implementation does nothing.
+     */
     protected void postConstraintApplied() {
 
     }
 
+    /**
+     * Returns the size of the elements which passes the filter constraint.
+     */
     public int getSize() {
         return filteredSize;
     }
 
-    public Object getElementAt(int index) {
-        return getFilteredModel().getElementAt(indexes[index]);
+    /**
+     * Returns the filtered element at a given position
+     */
+    public Object getElementAt(int filteredIndex) {
+        return getFilteredModel().getElementAt(getElementIndex(filteredIndex));
     }
 
+    /**
+     * Returns the element index for a filtered index
+     * 
+     * @param filteredIndex
+     *            the filtered index
+     * @return the unfiltered index of the filtered model
+     */
+    protected int getElementIndex(int filteredIndex) {
+        return indexes[filteredIndex];
+    }
+
     public void contentsChanged(ListDataEvent e) {
         super.contentsChanged(e);
     }

Added: 
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/list/FilteredListModelTests.java
===================================================================
--- 
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/list/FilteredListModelTests.java
                               (rev 0)
+++ 
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/list/FilteredListModelTests.java
       2006-08-16 15:18:25 UTC (rev 1302)
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2002-2006 the original author or authors.
+ * 
+ * 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 org.springframework.richclient.list;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Observable;
+import java.util.Observer;
+
+import javax.swing.DefaultListModel;
+import javax.swing.ListModel;
+
+import junit.framework.TestCase;
+
+import org.springframework.core.closure.Constraint;
+
+/**
+ * @author Mathias Broekelmann
+ * 
+ */
+public class FilteredListModelTests extends TestCase {
+
+    private TestListModel listModel;
+
+    private TestConstraint filter;
+
+    private Object[] elements = new Object[] { "1", "2", "3", "4" };
+
+    protected void setUp() throws Exception {
+        listModel = new TestListModel();
+        for (int i = 0; i < elements.length; i++) {
+            listModel.addElement(elements[i]);
+        }
+        filter = new TestConstraint();
+    }
+
+    protected void tearDown() throws Exception {
+        listModel = null;
+        filter = null;
+        elements = null;
+    }
+
+    public void testFilterWithoutElements() throws Exception {
+        ListModel filteredModel = new FilteredListModel(new 
DefaultListModel(), filter);
+        assertEquals(0, filteredModel.getSize());
+        assertEquals(1, filter.observeradded);
+    }
+
+    public void testNoFilterWithElements() throws Exception {
+        filter.filter = false;
+        ListModel filteredModel = new FilteredListModel(listModel, filter);
+        assertEquals(listModel.getSize(), filteredModel.getSize());
+        assertEquals(listModel.getSize(), filter.testCalled);
+    }
+
+    public void testPassThroughFilterWithElements() throws Exception {
+        ListModel filteredModel = new FilteredListModel(listModel, filter);
+        assertEquals(0, filteredModel.getSize());
+    }
+
+    public void testFilterWithElements1() throws Exception {
+        filter.elements = Arrays.asList(new Object[] { "2", "4" });
+        ListModel filteredModel = new FilteredListModel(listModel, filter);
+        assertEquals(filter.elements.size(), filteredModel.getSize());
+    }
+
+    public void testFilterWithElements2() throws Exception {
+        filter.elements = Arrays.asList(new Object[] { "2", "4", "9999" });
+        ListModel filteredModel = new FilteredListModel(listModel, filter);
+        assertEquals(2, filteredModel.getSize());
+        assertEquals("2", filteredModel.getElementAt(0));
+        assertEquals("4", filteredModel.getElementAt(1));
+    }
+
+    public void testFilterWithUpdatingModel() throws Exception {
+        filter.elements = Arrays.asList(new Object[] { "2", "4", "9999" });
+        ListModel filteredModel = new FilteredListModel(listModel, filter);
+        assertEquals(2, filteredModel.getSize());
+        filter.testCalled = 0;
+        listModel.addElement("1234");
+        assertEquals(listModel.getSize(), filter.testCalled);
+        assertEquals("2", filteredModel.getElementAt(0));
+        assertEquals("4", filteredModel.getElementAt(1));
+        listModel.addElement("9999");
+        assertEquals(3, filteredModel.getSize());
+        assertEquals("2", filteredModel.getElementAt(0));
+        assertEquals("4", filteredModel.getElementAt(1));
+        assertEquals("9999", filteredModel.getElementAt(2));
+        listModel.removeElement("2");
+        assertEquals(2, filteredModel.getSize());
+        assertEquals("4", filteredModel.getElementAt(0));
+        assertEquals("9999", filteredModel.getElementAt(1));
+    }
+
+    public void testObserver() throws Exception {
+        filter.elements = Arrays.asList(new Object[] { "2", "4" });
+        ListModel filteredModel = new FilteredListModel(listModel, filter);
+        assertEquals(2, filteredModel.getSize());
+        filter.testCalled = 0;
+        filter.elements = Arrays.asList(new Object[] { "1" });
+        filter.changed();
+        filter.notifyObservers();
+        assertEquals(listModel.getSize(), filter.testCalled);
+        assertEquals(filter.elements.size(), filteredModel.getSize());
+    }
+
+    private static class TestConstraint extends Observable implements 
Constraint {
+
+        boolean filter = true;
+
+        int testCalled = 0;
+
+        Collection elements = Collections.EMPTY_LIST;
+
+        int observeradded = 0;
+
+        public boolean test(Object argument) {
+            testCalled++;
+            if (filter) {
+                return elements.contains(argument);
+            }
+            return true;
+        }
+
+        void changed() {
+            setChanged();
+        }
+
+        public synchronized void addObserver(Observer o) {
+            observeradded++;
+            super.addObserver(o);
+        }
+    }
+
+    private static class TestListModel extends DefaultListModel {
+    }
+}


Property changes on: 
trunk/spring-richclient/support/src/test/java/org/springframework/richclient/list/FilteredListModelTests.java
___________________________________________________________________
Name: svn:keywords
   + URL Author Revision Date
Name: svn:eol-style
   + native


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
spring-rich-c-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/spring-rich-c-cvs

Reply via email to