View Javadoc

1   /*
2   
3       dsh-venn  Lightweight components for venn diagrams.
4       Copyright (c) 2009-2013 held jointly by the individual authors.
5   
6       This library is free software; you can redistribute it and/or modify it
7       under the terms of the GNU Lesser General Public License as published
8       by the Free Software Foundation; either version 3 of the License, or (at
9       your option) any later version.
10  
11      This library is distributed in the hope that it will be useful, but WITHOUT
12      ANY WARRANTY; with out even the implied warranty of MERCHANTABILITY or
13      FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14      License for more details.
15  
16      You should have received a copy of the GNU Lesser General Public License
17      along with this library;  if not, write to the Free Software Foundation,
18      Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA.
19  
20      > http://www.fsf.org/licensing/licenses/lgpl.html
21      > http://www.opensource.org/licenses/lgpl-license.php
22  
23  */
24  package org.dishevelled.venn.model;
25  
26  import java.util.HashSet;
27  import java.util.Set;
28  
29  import com.google.common.base.Joiner;
30  
31  import org.dishevelled.observable.ObservableSet;
32  
33  import org.dishevelled.observable.event.SetChangeEvent;
34  import org.dishevelled.observable.event.SetChangeListener;
35  
36  import org.dishevelled.observable.impl.ObservableSetImpl;
37  
38  /**
39   * Selection view.
40   *
41   * @param <E> value type
42   * @author  Michael Heuer
43   * @version $Revision$ $Date$
44   */
45  final class SelectionView<E>
46      extends ObservableSetImpl<E>
47  {
48      /** Default size. */
49      private static final int DEFAULT_SIZE = 16;
50  
51      /** Union view. */
52      private final Set<E> union;
53  
54      /** Purge selection. */
55      private final SetChangeListener<E> purgeSelection = new SetChangeListener<E>()
56          {
57              /** {@inheritDoc} */
58              public void setChanged(final SetChangeEvent<E> event)
59              {
60                  purgeSelection();
61              }
62          };
63  
64  
65      /**
66       * Create a new selection view with the specified views.
67       *
68       * @param union union view
69       * @param views variable number of views
70       */
71      SelectionView(final Set<E> union, final ObservableSet<E>... views)
72      {
73          super(new HashSet<E>(Math.max(DEFAULT_SIZE, union == null ? DEFAULT_SIZE : union.size())));
74          this.union = union;
75          for (ObservableSet<E> view : views)
76          {
77              view.addSetChangeListener(purgeSelection);
78          }
79      }
80  
81  
82      /**
83       * Remove elements from the selection view not present in the union view.
84       */
85      private void purgeSelection()
86      {
87          Set<E> toRemove = new HashSet<E>(Math.max(DEFAULT_SIZE, (int) (size() / 10)));
88          for (E e : this)
89          {
90              if (!union.contains(e))
91              {
92                  toRemove.add(e);
93              }
94          }
95          removeAll(toRemove);
96      }
97  
98      /** {@inheritDoc} */
99      protected boolean preAdd(final E e)
100     {
101         if (!union.contains(e))
102         {
103             throw new IllegalArgumentException("can not select an element not in union");
104         }
105         return super.preAdd(e);
106     }
107 
108     /** {@inheritDoc} */
109     public String toString()
110     {
111         StringBuilder sb = new StringBuilder();
112         sb.append("[");
113         Joiner.on(", ").appendTo(sb, this);
114         sb.append("]");
115         return sb.toString();
116     }
117 }