001    /* SizeSequence.java --
002       Copyright (C) 2002, 2006, Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package javax.swing;
039    
040    import java.util.Arrays;
041    
042    /**
043     * A sequence of values that represent the dimensions (widths or heights) of
044     * some collection of items (for example, the widths of the columns in a table).
045     *
046     * @author      Andrew Selkirk
047     */
048    public class SizeSequence
049    {
050      // TODO: Sun's API specification for this class contains an implementation
051      // note regarding the encoding for the element sizes.  We currently use the
052      // simple size encoding but we should look at improving this.
053    
054      /** Storage for the element sizes. */
055      private int[] sizes;
056    
057      /**
058       * Creates a new empty <code>SizeSequence</code> instance.
059       */
060      public SizeSequence()
061      {
062        sizes = new int[0];
063      }
064    
065      /**
066       * Creates a new <code>SizeSequence</code> instance with the specified number
067       * of elements, each having a size of 0.
068       *
069       * @param numEntries  the number of elements.
070       */
071      public SizeSequence(int numEntries)
072      {
073        this(numEntries, 0);
074      }
075    
076      /**
077       * Creates a new <code>SizeSequence</code> instance with the specified number
078       * of elements all having the same size (<code>value</code>).
079       *
080       * @param numEntries  the number of elements.
081       * @param value  the value for each element.
082       */
083      public SizeSequence(int numEntries, int value)
084      {
085        sizes = new int[numEntries];
086        Arrays.fill(sizes, value);
087      }
088    
089      /**
090       * Creates a new <code>SizeSequence</code> instance using the specified
091       * element sizes.
092       *
093       * @param sizes  the element sizes (<code>null</code> not permitted).
094       */
095      public SizeSequence(int[] sizes)
096      {
097        this.sizes = (int[]) sizes.clone();
098      }
099    
100      /**
101       * Sets the size of the element at the specified index.
102       *
103       * @param index  the index.
104       * @param size  the size.
105       */
106      public void setSize(int index, int size)
107      {
108        if (index >= 0 && index < sizes.length)
109          sizes[index] = size;
110      }
111    
112      /**
113       * Returns the index of the element that contains the specified position.
114       *
115       * @param position  the position.
116       *
117       * @return The index of the element that contains the specified position.
118       */
119      public int getIndex(int position)
120      {
121        int i = 0;
122        int runningTotal = 0;
123        while (i < sizes.length && position >= runningTotal + sizes[i])
124          {
125            runningTotal += sizes[i];
126            i++;
127          }
128        return i;
129      }
130    
131      /**
132       * Returns the size of the specified element, or 0 if the element index is
133       * outside the defined range.
134       *
135       * @param index  the element index.
136       *
137       * @return The size of the specified element, or 0 if the element index is
138       *     outside the defined range.
139       */
140      public int getSize(int index)
141      {
142        if (index < 0 || index >= sizes.length)
143          return 0;
144        return sizes[index];
145      }
146    
147      /**
148       * Sets the sizes for the elements in the sequence.
149       *
150       * @param sizes  the element sizes (<code>null</code> not permitted).
151       */
152      public void setSizes(int[] sizes)
153      {
154        this.sizes = (int[]) sizes.clone();
155      }
156    
157      /**
158       * Returns an array containing the sizes for all the elements in the sequence.
159       *
160       * @return The element sizes.
161       */
162      public int[] getSizes()
163      {
164        return (int[]) sizes.clone();
165      }
166    
167      /**
168       * Returns the position of the specified element.
169       *
170       * @param index  the element index.
171       *
172       * @return The position.
173       */
174      public int getPosition(int index)
175      {
176        int position;
177        int loop;
178        position = 0;
179        for (loop = 0; loop < index; loop++)
180          position += sizes[loop];
181        return position;
182    
183      }
184    
185      /**
186       * Inserts new entries into the sequence at the <code>start</code> position.
187       * There are <code>length</code> new entries each having the specified
188       * <code>value</code>.
189       *
190       * @param start  the start element.
191       * @param length  the number of elements to insert.
192       * @param value  the size for each of the new elements.
193       */
194      public void insertEntries(int start, int length, int value)
195      {
196        int[] newSizes = new int[sizes.length + length];
197        System.arraycopy(sizes, 0, newSizes, 0, start);
198        for (int i = start; i < start + length; i++)
199          newSizes[i] = value;
200        System.arraycopy(sizes, start, newSizes, start + length,
201                         sizes.length - start);
202        sizes = newSizes;
203      }
204    
205      /**
206       * Removes the element(s) at index <code>start</code> (the number of elements
207       * removed is <code>length</code>).
208       *
209       * @param start  the index of the first element to remove.
210       * @param length  the number of elements to remove.
211       */
212      public void removeEntries(int start, int length)
213      {
214        // Sanity check.
215        if ((start + length) > sizes.length)
216          throw new IllegalArgumentException("Specified start/length that "
217                                             + "is greater than available sizes");
218    
219        int[] newSizes = new int[sizes.length - length];
220        System.arraycopy(sizes, 0, newSizes, 0, start);
221        System.arraycopy(sizes, start + length, newSizes, start,
222                         sizes.length - start - length);
223        sizes = newSizes;
224      }
225    }