SubFilterList.java
  1  // HTMLParser Library $Name: v1_6_20060319 $ - A java-based parser for HTML
  2  // http://sourceforge.org/projects/htmlparser
  3  // Copyright (C) 2005 Derrick Oswald
  4  //
  5  // Revision Control Information
  6  //
  7  // $Source: /cvsroot/htmlparser/htmlparser/src/org/htmlparser/parserapplications/filterbuilder/SubFilterList.java,v $
  8  // $Author: derrickoswald $
  9  // $Date: 2005/04/12 11:27:42 $
 10  // $Revision: 1.3 $
 11  //
 12  // This library is free software; you can redistribute it and/or
 13  // modify it under the terms of the GNU Lesser General Public
 14  // License as published by the Free Software Foundation; either
 15  // version 2.1 of the License, or (at your option) any later version.
 16  //
 17  // This library is distributed in the hope that it will be useful,
 18  // but WITHOUT ANY WARRANTY; without even the implied warranty of
 19  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 20  // Lesser General Public License for more details.
 21  //
 22  // You should have received a copy of the GNU Lesser General Public
 23  // License along with this library; if not, write to the Free Software
 24  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 25  //
 26  
 27  package org.htmlparser.parserapplications.filterbuilder;
 28  
 29  import java.awt.*;
 30  
 31  import javax.swing.*;
 32  import javax.swing.border.*;
 33  
 34  import org.htmlparser.NodeFilter;
 35  import org.htmlparser.parserapplications.filterbuilder.layouts.VerticalLayoutManager;
 36  
 37  /**
 38   * A helper class for lists of filters within filters.
 39   */
 40  public class SubFilterList
 41      extends
 42          JPanel
 43  {
 44      /**
 45       * Padding for the drop target.
 46       */
 47      protected int mExtra = 25; // for now
 48  
 49      /**
 50       * The drop target spacer at the bottom of the list.
 51       */
 52      protected Component mSpacer;
 53  
 54      /**
 55       * The parent filter wrapper.
 56       */
 57      protected Filter mHome;
 58  
 59      /**
 60       * The textual title for the list.
 61       */
 62      protected String mTitle;
 63  
 64      /**
 65       * The number of filters limit.
 66       */
 67      protected int mMax;
 68  
 69      /**
 70       * Creates a container panel.
 71       * Set the panel minimum size to the same width as the container
 72       * but with a bit of extra length.
 73       * @param home The filter we belong to.
 74       * @param title The border title.
 75       * @param max The maximum number of filters in the list (0 for no limit).
 76       */
 77      public SubFilterList (Filter home, String title, int max)
 78      {
 79          mHome = home;
 80          mTitle = title;
 81          mMax = max;
 82  
 83          // not quite:
 84          // new BoxLayout (this, BoxLayout.Y_AXIS));
 85          setLayout (new VerticalLayoutManager ());
 86  	    addSpacer ();
 87  	    setSelected (false);
 88      }
 89  
 90      /**
 91       * Set the 'selected look' for the component.
 92       * @param selected If <code>true</code>, 'select' this component,
 93       * otherwise 'deselect' it.
 94       */
 95      public void setSelected (boolean selected)
 96      {
 97          if (selected)
 98      	    setBorder (
 99      		        new CompoundBorder (
100      		            new TitledBorder (
101      		                null,
102      		                mTitle,
103      	                    TitledBorder.LEFT,
104      	                    TitledBorder.TOP),
105      	                    new CompoundBorder (
106  	                            new LineBorder (Color.green, 2),
107  	                            new EmptyBorder (1, 1, 1, 1))));
108          else
109      	    setBorder (
110      		        new CompoundBorder (
111      		            new TitledBorder (
112      		                null,
113      		                mTitle,
114      	                    TitledBorder.LEFT,
115      	                    TitledBorder.TOP),
116      	                new EmptyBorder (3,3,3,3)));
117      }
118  
119      /**
120       * Stuff a spacer component at the end of the list.
121       */
122      protected void addSpacer ()
123      {
124          Dimension dimension;
125          Insets insets;
126          
127          // set the command area size by adding a rigid area
128          dimension = mHome.getSize ();
129          insets = mHome.getInsets ();
130          // todo: this should resize with the container
131          dimension.setSize (dimension.width - insets.left - insets.right, mExtra);
132          mSpacer = Box.createRigidArea (dimension);
133          add (mSpacer);
134      }
135  
136      /**
137       * Remove the spacer component at the end of the list.
138       */
139      protected void removeSpacer ()
140      {
141          remove (mSpacer);
142          mSpacer = null;
143      }
144  
145      /**
146       * Get the components in which to drop commands.
147       * @return The component to act as a drop target.
148       */
149      public Component[] getDropTargets ()
150      {
151          return (new Component[] { this });
152      }
153  
154      /**
155       * Add a filter to the container contents.
156       * @param filter The command to add to the container.
157       */
158      public void addFilter (Filter filter)
159      {
160          int count;
161          
162          count = getComponentCount ();
163          if (null != mSpacer)
164              count--; // insert before the spacer
165          addFilter (filter, count);
166      }
167  
168      /**
169       * Add a filter to the container at a specific position.
170       * @param filter The filter to add to the container.
171       * @param index The index at which to add it.
172       */
173      public void addFilter (Filter filter, int index)
174      {
175          NodeFilter[] before;
176          NodeFilter[] after;
177          int offset;
178  
179          add (filter, index);
180          before = mHome.getSubNodeFilters ();
181          after = new NodeFilter[before.length + 1];
182          offset = 0;
183          for (int i = 0; i < after.length; i++)
184              after[i] = (i == index) ? filter : before[offset++];
185          mHome.setSubNodeFilters (after);
186          if ((null != mSpacer) && (0 != mMax) && (after.length >= mMax))
187              removeSpacer ();
188      }        
189  
190      /**
191       * Remove a filter from the container.
192       * @param filter The filter to remove from the container.
193       */
194      public void removeFilter (Filter filter)
195      {
196          Filter[] filters;
197          int index;
198          
199          filters = getFilters ();
200          index = -1;
201          for (int i = 0; ((-1 == index) && (i < filters.length)); i++)
202              if (filter == filters[i])
203                  index = i;
204          if (-1 != index)
205              removeFilter (index);
206      }
207  
208      /**
209       * Remove a filter from the container.
210       * @param index The index of the filter to remove from the container.
211       */
212      public void removeFilter (int index)
213      {
214          NodeFilter[] before;
215          NodeFilter[] after;
216          int offset;
217  
218          remove (index);
219          before = mHome.getSubNodeFilters ();
220          if (0 != before.length)
221          {
222  	        after = new NodeFilter[before.length - 1];
223  	        offset = 0;
224  	        for (int i = 0; i < before.length; i++)
225  	            if (i != index)
226  	                after[offset++] = before[i];
227  	        mHome.setSubNodeFilters (after);
228  	        if ((null == mSpacer) && (0 != mMax) && (after.length < mMax))
229  	            addSpacer ();
230          }
231      }
232  
233      /**
234       * Return the list of filters in this container.
235       * @return The list of contained filters.
236       */
237      public Filter[] getFilters ()
238      {
239          NodeFilter[] list;
240          Filter[] ret;
241  
242          list = mHome.getSubNodeFilters ();
243          ret = new Filter[list.length];
244          System.arraycopy (list, 0, ret, 0, list.length);
245  
246          return (ret);
247      }
248  
249      /**
250       * Check if our maximum number of filters limit has been reached.
251       * @return <code>true</code> if the sublist can accept one more filter,
252       * <code>false</code> otherwise.
253       */
254      public boolean canAccept ()
255      {
256          int count;
257          boolean ret;
258  
259          if (0 == mMax)
260              ret = true;
261          else
262          {
263  	        count = getComponentCount ();
264  	        if (null != mSpacer)
265  	            count--;
266  	        ret = count < mMax;
267          }
268  
269          return (ret);
270      }
271  
272      /**
273       * Get the bytes for this command as a String.
274       * @param indent The number of spaces to indent a block.
275       * @param level The current indentation level.
276       * The first non-whitespace character should be at
277       * indented <code>indent</code> * <code>level</code> spaces.
278       * @return The string representing this command.
279       */
280      public String toString (int indent, int level)
281      {
282          Filter[] filters;
283          StringBuffer ret;
284          
285          ret = new StringBuffer ();
286  
287          filters = getFilters ();
288          for (int i = 0; i < filters.length; i++)
289          {
290              ret.append (filters[i].toString ());
291              if (i + 1 != filters.length)
292                  ret.append ("\n");
293          }
294          
295          return (ret.toString ());
296      }
297      
298  }