001/* SizeSequence.java --
002   Copyright (C) 2002, 2006, Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038package javax.swing;
039
040import 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 */
048public 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}