9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.swing; 27 28 /** 29 * A <code>SizeSequence</code> object 30 * efficiently maintains an ordered list 31 * of sizes and corresponding positions. 32 * One situation for which <code>SizeSequence</code> 33 * might be appropriate is in a component 34 * that displays multiple rows of unequal size. 35 * In this case, a single <code>SizeSequence</code> 36 * object could be used to track the heights 37 * and Y positions of all rows. 38 * <p> 39 * Another example would be a multi-column component, 40 * such as a <code>JTable</code>, 41 * in which the column sizes are not all equal. 42 * The <code>JTable</code> might use a single 43 * <code>SizeSequence</code> object 44 * to store the widths and X positions of all the columns. 45 * The <code>JTable</code> could then use the 46 * <code>SizeSequence</code> object 47 * to find the column corresponding to a certain position. 48 * The <code>JTable</code> could update the 49 * <code>SizeSequence</code> object 50 * whenever one or more column sizes changed. 51 * 52 * <p> 53 * The following figure shows the relationship between size and position data 54 * for a multi-column component. 55 * 56 * <center> 57 * <img src="doc-files/SizeSequence-1.gif" width=384 height = 100 58 * alt="The first item begins at position 0, the second at the position equal 59 to the size of the previous item, and so on."> 60 * </center> 61 * <p> 62 * In the figure, the first index (0) corresponds to the first column, 63 * the second index (1) to the second column, and so on. 64 * The first column's position starts at 0, 65 * and the column occupies <em>size<sub>0</sub></em> pixels, 66 * where <em>size<sub>0</sub></em> is the value returned by 67 * <code>getSize(0)</code>. 68 * Thus, the first column ends at <em>size<sub>0</sub></em> - 1. 69 * The second column then begins at 70 * the position <em>size<sub>0</sub></em> 71 * and occupies <em>size<sub>1</sub></em> (<code>getSize(1)</code>) pixels. 72 * <p> 73 * Note that a <code>SizeSequence</code> object simply represents intervals 74 * along an axis. 75 * In our examples, the intervals represent height or width in pixels. 76 * However, any other unit of measure (for example, time in days) 77 * could be just as valid. 78 * 79 * 80 * <h3>Implementation Notes</h3> 81 * 82 * Normally when storing the size and position of entries, 83 * one would choose between 84 * storing the sizes or storing their positions 85 * instead. The two common operations that are needed during 86 * rendering are: <code>getIndex(position)</code> 87 * and <code>setSize(index, size)</code>. 88 * Whichever choice of internal format is made one of these 89 * operations is costly when the number of entries becomes large. 90 * If sizes are stored, finding the index of the entry 91 * that encloses a particular position is linear in the 92 * number of entries. If positions are stored instead, setting 93 * the size of an entry at a particular index requires updating 94 * the positions of the affected entries, which is also a linear 95 * calculation. 96 * <p> 97 * Like the above techniques this class holds an array of N integers 98 * internally but uses a hybrid encoding, which is halfway 99 * between the size-based and positional-based approaches. 100 * The result is a data structure that takes the same space to store 101 * the information but can perform most operations in Log(N) time 102 * instead of O(N), where N is the number of entries in the list. 103 * <p> 104 * Two operations that remain O(N) in the number of entries are 105 * the <code>insertEntries</code> 106 * and <code>removeEntries</code> methods, both 107 * of which are implemented by converting the internal array to 108 * a set of integer sizes, copying it into the new array, and then 109 * reforming the hybrid representation in place. 110 * 111 * @author Philip Milne 112 * @since 1.3 113 */ 114 115 /* 116 * Each method is implemented by taking the minimum and 117 * maximum of the range of integers that need to be operated 118 * upon. All the algorithms work by dividing this range 119 * into two smaller ranges and recursing. The recursion 120 * is terminated when the upper and lower bounds are equal. 121 */ 122 123 public class SizeSequence { 124 125 private static int[] emptyArray = new int[0]; 126 private int a[]; 127 128 /** 129 * Creates a new <code>SizeSequence</code> object 130 * that contains no entries. To add entries, you 131 * can use <code>insertEntries</code> or <code>setSizes</code>. 132 * 133 * @see #insertEntries 134 * @see #setSizes(int[]) 135 */ 136 public SizeSequence() { 137 a = emptyArray; 138 } 139 140 /** 141 * Creates a new <code>SizeSequence</code> object 142 * that contains the specified number of entries, 143 * all initialized to have size 0. 144 * 145 * @param numEntries the number of sizes to track 146 * @exception NegativeArraySizeException if 147 * <code>numEntries < 0</code> 148 */ 149 public SizeSequence(int numEntries) { 150 this(numEntries, 0); 151 } 152 153 /** 154 * Creates a new <code>SizeSequence</code> object 155 * that contains the specified number of entries, 156 * all initialized to have size <code>value</code>. 157 * 158 * @param numEntries the number of sizes to track 159 * @param value the initial value of each size 160 */ 161 public SizeSequence(int numEntries, int value) { 162 this(); 163 insertEntries(0, numEntries, value); 164 } 165 166 /** 167 * Creates a new <code>SizeSequence</code> object 168 * that contains the specified sizes. 169 * 170 * @param sizes the array of sizes to be contained in 171 * the <code>SizeSequence</code> 172 */ 173 public SizeSequence(int[] sizes) { 174 this(); 175 setSizes(sizes); 176 } 177 178 /** 179 * Resets the size sequence to contain <code>length</code> items 180 * all with a size of <code>size</code>. 181 */ 182 void setSizes(int length, int size) { 183 if (a.length != length) { 184 a = new int[length]; 185 } 186 setSizes(0, length, size); 187 } 188 189 private int setSizes(int from, int to, int size) { 190 if (to <= from) { 191 return 0; 192 } 193 int m = (from + to)/2; 194 a[m] = size + setSizes(from, m, size); 195 return a[m] + setSizes(m + 1, to, size); 196 } 197 198 /** 199 * Resets this <code>SizeSequence</code> object, 200 * using the data in the <code>sizes</code> argument. 201 * This method reinitializes this object so that it 202 * contains as many entries as the <code>sizes</code> array. 203 * Each entry's size is initialized to the value of the 204 * corresponding item in <code>sizes</code>. 205 * 206 * @param sizes the array of sizes to be contained in 207 * this <code>SizeSequence</code> 208 */ 209 public void setSizes(int[] sizes) { 210 if (a.length != sizes.length) { 211 a = new int[sizes.length]; 212 } 213 setSizes(0, a.length, sizes); 214 } 215 216 private int setSizes(int from, int to, int[] sizes) { 217 if (to <= from) { 218 return 0; 219 } 220 int m = (from + to)/2; 221 a[m] = sizes[m] + setSizes(from, m, sizes); 222 return a[m] + setSizes(m + 1, to, sizes); 223 } 224 225 /** 226 * Returns the size of all entries. 227 * 228 * @return a new array containing the sizes in this object 229 */ 230 public int[] getSizes() { 231 int n = a.length; 232 int[] sizes = new int[n]; 233 getSizes(0, n, sizes); 234 return sizes; 235 } 236 237 private int getSizes(int from, int to, int[] sizes) { 238 if (to <= from) { 239 return 0; 240 } 241 int m = (from + to)/2; 242 sizes[m] = a[m] - getSizes(from, m, sizes); 243 return a[m] + getSizes(m + 1, to, sizes); 244 } 245 246 /** 247 * Returns the start position for the specified entry. 248 * For example, <code>getPosition(0)</code> returns 0, 249 * <code>getPosition(1)</code> is equal to 250 * <code>getSize(0)</code>, 251 * <code>getPosition(2)</code> is equal to 252 * <code>getSize(0)</code> + <code>getSize(1)</code>, 253 * and so on. 254 * <p>Note that if <code>index</code> is greater than 255 * <code>length</code> the value returned may 256 * be meaningless. 257 * 258 * @param index the index of the entry whose position is desired 259 * @return the starting position of the specified entry 260 */ 261 public int getPosition(int index) { 262 return getPosition(0, a.length, index); 263 } 264 265 private int getPosition(int from, int to, int index) { 266 if (to <= from) { 267 return 0; 268 } 269 int m = (from + to)/2; 270 if (index <= m) { 271 return getPosition(from, m, index); 272 } 273 else { 274 return a[m] + getPosition(m + 1, to, index); 275 } 276 } 277 278 /** 279 * Returns the index of the entry 280 * that corresponds to the specified position. 281 * For example, <code>getIndex(0)</code> is 0, 282 * since the first entry always starts at position 0. 283 * 284 * @param position the position of the entry 285 * @return the index of the entry that occupies the specified position 286 */ 287 public int getIndex(int position) { 288 return getIndex(0, a.length, position); 289 } 290 291 private int getIndex(int from, int to, int position) { 292 if (to <= from) { 293 return from; 294 } 295 int m = (from + to)/2; 296 int pivot = a[m]; 297 if (position < pivot) { 298 return getIndex(from, m, position); 299 } 300 else { 301 return getIndex(m + 1, to, position - pivot); 302 } 303 } 304 305 /** 306 * Returns the size of the specified entry. 307 * If <code>index</code> is out of the range 308 * <code>(0 <= index < getSizes().length)</code> 309 * the behavior is unspecified. 310 * 311 * @param index the index corresponding to the entry 312 * @return the size of the entry 313 */ 314 public int getSize(int index) { 315 return getPosition(index + 1) - getPosition(index); 316 } 317 318 /** 319 * Sets the size of the specified entry. 320 * Note that if the value of <code>index</code> 321 * does not fall in the range: 322 * <code>(0 <= index < getSizes().length)</code> 323 * the behavior is unspecified. 324 * 325 * @param index the index corresponding to the entry 326 * @param size the size of the entry 327 */ 328 public void setSize(int index, int size) { 329 changeSize(0, a.length, index, size - getSize(index)); 330 } 331 332 private void changeSize(int from, int to, int index, int delta) { 333 if (to <= from) { 334 return; 335 } 336 int m = (from + to)/2; 337 if (index <= m) { 338 a[m] += delta; 339 changeSize(from, m, index, delta); 340 } 341 else { 342 changeSize(m + 1, to, index, delta); 343 } 344 } 345 346 /** 347 * Adds a contiguous group of entries to this <code>SizeSequence</code>. 348 * Note that the values of <code>start</code> and 349 * <code>length</code> must satisfy the following 350 * conditions: <code>(0 <= start < getSizes().length) 351 * AND (length >= 0)</code>. If these conditions are 352 * not met, the behavior is unspecified and an exception 353 * may be thrown. 354 * 355 * @param start the index to be assigned to the first entry 356 * in the group 357 * @param length the number of entries in the group 358 * @param value the size to be assigned to each new entry 359 * @exception ArrayIndexOutOfBoundsException if the parameters 360 * are outside of the range: 361 * (<code>0 <= start < (getSizes().length)) AND (length >= 0)</code> 362 */ 363 public void insertEntries(int start, int length, int value) { 364 int sizes[] = getSizes(); 365 int end = start + length; 366 int n = a.length + length; 367 a = new int[n]; 368 for (int i = 0; i < start; i++) { 369 a[i] = sizes[i] ; 370 } 371 for (int i = start; i < end; i++) { 372 a[i] = value ; 373 } 374 for (int i = end; i < n; i++) { 375 a[i] = sizes[i-length] ; 376 } 377 setSizes(a); 378 } 379 380 /** 381 * Removes a contiguous group of entries 382 * from this <code>SizeSequence</code>. 383 * Note that the values of <code>start</code> and 384 * <code>length</code> must satisfy the following 385 * conditions: <code>(0 <= start < getSizes().length) 386 * AND (length >= 0)</code>. If these conditions are 387 * not met, the behavior is unspecified and an exception 388 * may be thrown. 389 * 390 * @param start the index of the first entry to be removed 391 * @param length the number of entries to be removed 392 */ 393 public void removeEntries(int start, int length) { 394 int sizes[] = getSizes(); 395 int end = start + length; 396 int n = a.length - length; 397 a = new int[n]; 398 for (int i = 0; i < start; i++) { 399 a[i] = sizes[i] ; 400 } 401 for (int i = start; i < n; i++) { 402 a[i] = sizes[i+length] ; 403 } 404 setSizes(a); 405 } 406 } | 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.swing; 27 28 /** 29 * A {@code SizeSequence} object 30 * efficiently maintains an ordered list 31 * of sizes and corresponding positions. 32 * One situation for which {@code SizeSequence} 33 * might be appropriate is in a component 34 * that displays multiple rows of unequal size. 35 * In this case, a single {@code SizeSequence} 36 * object could be used to track the heights 37 * and Y positions of all rows. 38 * <p> 39 * Another example would be a multi-column component, 40 * such as a {@code JTable}, 41 * in which the column sizes are not all equal. 42 * The {@code JTable} might use a single 43 * {@code SizeSequence} object 44 * to store the widths and X positions of all the columns. 45 * The {@code JTable} could then use the 46 * {@code SizeSequence} object 47 * to find the column corresponding to a certain position. 48 * The {@code JTable} could update the 49 * {@code SizeSequence} object 50 * whenever one or more column sizes changed. 51 * 52 * <p> 53 * The following figure shows the relationship between size and position data 54 * for a multi-column component. 55 * 56 * <center> 57 * <img src="doc-files/SizeSequence-1.gif" width=384 height = 100 58 * alt="The first item begins at position 0, the second at the position equal 59 to the size of the previous item, and so on."> 60 * </center> 61 * <p> 62 * In the figure, the first index (0) corresponds to the first column, 63 * the second index (1) to the second column, and so on. 64 * The first column's position starts at 0, 65 * and the column occupies <em>size<sub>0</sub></em> pixels, 66 * where <em>size<sub>0</sub></em> is the value returned by 67 * {@code getSize(0)}. 68 * Thus, the first column ends at <em>size<sub>0</sub></em> - 1. 69 * The second column then begins at 70 * the position <em>size<sub>0</sub></em> 71 * and occupies <em>size<sub>1</sub></em> ({@code getSize(1)}) pixels. 72 * <p> 73 * Note that a {@code SizeSequence} object simply represents intervals 74 * along an axis. 75 * In our examples, the intervals represent height or width in pixels. 76 * However, any other unit of measure (for example, time in days) 77 * could be just as valid. 78 * 79 * 80 * <h3>Implementation Notes</h3> 81 * 82 * Normally when storing the size and position of entries, 83 * one would choose between 84 * storing the sizes or storing their positions 85 * instead. The two common operations that are needed during 86 * rendering are: {@code getIndex(position)} 87 * and {@code setSize(index, size)}. 88 * Whichever choice of internal format is made one of these 89 * operations is costly when the number of entries becomes large. 90 * If sizes are stored, finding the index of the entry 91 * that encloses a particular position is linear in the 92 * number of entries. If positions are stored instead, setting 93 * the size of an entry at a particular index requires updating 94 * the positions of the affected entries, which is also a linear 95 * calculation. 96 * <p> 97 * Like the above techniques this class holds an array of N integers 98 * internally but uses a hybrid encoding, which is halfway 99 * between the size-based and positional-based approaches. 100 * The result is a data structure that takes the same space to store 101 * the information but can perform most operations in Log(N) time 102 * instead of O(N), where N is the number of entries in the list. 103 * <p> 104 * Two operations that remain O(N) in the number of entries are 105 * the {@code insertEntries} 106 * and {@code removeEntries} methods, both 107 * of which are implemented by converting the internal array to 108 * a set of integer sizes, copying it into the new array, and then 109 * reforming the hybrid representation in place. 110 * 111 * @author Philip Milne 112 * @since 1.3 113 */ 114 115 /* 116 * Each method is implemented by taking the minimum and 117 * maximum of the range of integers that need to be operated 118 * upon. All the algorithms work by dividing this range 119 * into two smaller ranges and recursing. The recursion 120 * is terminated when the upper and lower bounds are equal. 121 */ 122 123 public class SizeSequence { 124 125 private static int[] emptyArray = new int[0]; 126 private int a[]; 127 128 /** 129 * Creates a new {@code SizeSequence} object 130 * that contains no entries. To add entries, you 131 * can use {@code insertEntries} or {@code setSizes}. 132 * 133 * @see #insertEntries 134 * @see #setSizes(int[]) 135 */ 136 public SizeSequence() { 137 a = emptyArray; 138 } 139 140 /** 141 * Creates a new {@code SizeSequence} object 142 * that contains the specified number of entries, 143 * all initialized to have size 0. 144 * 145 * @param numEntries the number of sizes to track 146 * @exception NegativeArraySizeException if 147 * {@code numEntries < 0} 148 */ 149 public SizeSequence(int numEntries) { 150 this(numEntries, 0); 151 } 152 153 /** 154 * Creates a new {@code SizeSequence} object 155 * that contains the specified number of entries, 156 * all initialized to have size {@code value}. 157 * 158 * @param numEntries the number of sizes to track 159 * @param value the initial value of each size 160 */ 161 public SizeSequence(int numEntries, int value) { 162 this(); 163 insertEntries(0, numEntries, value); 164 } 165 166 /** 167 * Creates a new {@code SizeSequence} object 168 * that contains the specified sizes. 169 * 170 * @param sizes the array of sizes to be contained in 171 * the {@code SizeSequence} 172 */ 173 public SizeSequence(int[] sizes) { 174 this(); 175 setSizes(sizes); 176 } 177 178 /** 179 * Resets the size sequence to contain {@code length} items 180 * all with a size of {@code size}. 181 */ 182 void setSizes(int length, int size) { 183 if (a.length != length) { 184 a = new int[length]; 185 } 186 setSizes(0, length, size); 187 } 188 189 private int setSizes(int from, int to, int size) { 190 if (to <= from) { 191 return 0; 192 } 193 int m = (from + to)/2; 194 a[m] = size + setSizes(from, m, size); 195 return a[m] + setSizes(m + 1, to, size); 196 } 197 198 /** 199 * Resets this {@code SizeSequence} object, 200 * using the data in the {@code sizes} argument. 201 * This method reinitializes this object so that it 202 * contains as many entries as the {@code sizes} array. 203 * Each entry's size is initialized to the value of the 204 * corresponding item in {@code sizes}. 205 * 206 * @param sizes the array of sizes to be contained in 207 * this {@code SizeSequence} 208 */ 209 public void setSizes(int[] sizes) { 210 if (a.length != sizes.length) { 211 a = new int[sizes.length]; 212 } 213 setSizes(0, a.length, sizes); 214 } 215 216 private int setSizes(int from, int to, int[] sizes) { 217 if (to <= from) { 218 return 0; 219 } 220 int m = (from + to)/2; 221 a[m] = sizes[m] + setSizes(from, m, sizes); 222 return a[m] + setSizes(m + 1, to, sizes); 223 } 224 225 /** 226 * Returns the size of all entries. 227 * 228 * @return a new array containing the sizes in this object 229 */ 230 public int[] getSizes() { 231 int n = a.length; 232 int[] sizes = new int[n]; 233 getSizes(0, n, sizes); 234 return sizes; 235 } 236 237 private int getSizes(int from, int to, int[] sizes) { 238 if (to <= from) { 239 return 0; 240 } 241 int m = (from + to)/2; 242 sizes[m] = a[m] - getSizes(from, m, sizes); 243 return a[m] + getSizes(m + 1, to, sizes); 244 } 245 246 /** 247 * Returns the start position for the specified entry. 248 * For example, {@code getPosition(0)} returns 0, 249 * {@code getPosition(1)} is equal to 250 * {@code getSize(0)}, 251 * {@code getPosition(2)} is equal to 252 * {@code getSize(0)} + {@code getSize(1)}, 253 * and so on. 254 * <p>Note that if {@code index} is greater than 255 * {@code length} the value returned may 256 * be meaningless. 257 * 258 * @param index the index of the entry whose position is desired 259 * @return the starting position of the specified entry 260 */ 261 public int getPosition(int index) { 262 return getPosition(0, a.length, index); 263 } 264 265 private int getPosition(int from, int to, int index) { 266 if (to <= from) { 267 return 0; 268 } 269 int m = (from + to)/2; 270 if (index <= m) { 271 return getPosition(from, m, index); 272 } 273 else { 274 return a[m] + getPosition(m + 1, to, index); 275 } 276 } 277 278 /** 279 * Returns the index of the entry 280 * that corresponds to the specified position. 281 * For example, {@code getIndex(0)} is 0, 282 * since the first entry always starts at position 0. 283 * 284 * @param position the position of the entry 285 * @return the index of the entry that occupies the specified position 286 */ 287 public int getIndex(int position) { 288 return getIndex(0, a.length, position); 289 } 290 291 private int getIndex(int from, int to, int position) { 292 if (to <= from) { 293 return from; 294 } 295 int m = (from + to)/2; 296 int pivot = a[m]; 297 if (position < pivot) { 298 return getIndex(from, m, position); 299 } 300 else { 301 return getIndex(m + 1, to, position - pivot); 302 } 303 } 304 305 /** 306 * Returns the size of the specified entry. 307 * If {@code index} is out of the range 308 * {@code (0 <= index < getSizes().length)} 309 * the behavior is unspecified. 310 * 311 * @param index the index corresponding to the entry 312 * @return the size of the entry 313 */ 314 public int getSize(int index) { 315 return getPosition(index + 1) - getPosition(index); 316 } 317 318 /** 319 * Sets the size of the specified entry. 320 * Note that if the value of {@code index} 321 * does not fall in the range: 322 * {@code (0 <= index < getSizes().length)} 323 * the behavior is unspecified. 324 * 325 * @param index the index corresponding to the entry 326 * @param size the size of the entry 327 */ 328 public void setSize(int index, int size) { 329 changeSize(0, a.length, index, size - getSize(index)); 330 } 331 332 private void changeSize(int from, int to, int index, int delta) { 333 if (to <= from) { 334 return; 335 } 336 int m = (from + to)/2; 337 if (index <= m) { 338 a[m] += delta; 339 changeSize(from, m, index, delta); 340 } 341 else { 342 changeSize(m + 1, to, index, delta); 343 } 344 } 345 346 /** 347 * Adds a contiguous group of entries to this {@code SizeSequence}. 348 * Note that the values of {@code start} and 349 * {@code length} must satisfy the following 350 * conditions: {@code (0 <= start < getSizes().length) 351 * AND (length >= 0)}. If these conditions are 352 * not met, the behavior is unspecified and an exception 353 * may be thrown. 354 * 355 * @param start the index to be assigned to the first entry 356 * in the group 357 * @param length the number of entries in the group 358 * @param value the size to be assigned to each new entry 359 * @exception ArrayIndexOutOfBoundsException if the parameters 360 * are outside of the range: 361 * ({@code 0 <= start < (getSizes().length)) AND (length >= 0)} 362 */ 363 public void insertEntries(int start, int length, int value) { 364 int sizes[] = getSizes(); 365 int end = start + length; 366 int n = a.length + length; 367 a = new int[n]; 368 for (int i = 0; i < start; i++) { 369 a[i] = sizes[i] ; 370 } 371 for (int i = start; i < end; i++) { 372 a[i] = value ; 373 } 374 for (int i = end; i < n; i++) { 375 a[i] = sizes[i-length] ; 376 } 377 setSizes(a); 378 } 379 380 /** 381 * Removes a contiguous group of entries 382 * from this {@code SizeSequence}. 383 * Note that the values of {@code start} and 384 * {@code length} must satisfy the following 385 * conditions: {@code (0 <= start < getSizes().length) 386 * AND (length >= 0)}. If these conditions are 387 * not met, the behavior is unspecified and an exception 388 * may be thrown. 389 * 390 * @param start the index of the first entry to be removed 391 * @param length the number of entries to be removed 392 */ 393 public void removeEntries(int start, int length) { 394 int sizes[] = getSizes(); 395 int end = start + length; 396 int n = a.length - length; 397 a = new int[n]; 398 for (int i = 0; i < start; i++) { 399 a[i] = sizes[i] ; 400 } 401 for (int i = start; i < n; i++) { 402 a[i] = sizes[i+length] ; 403 } 404 setSizes(a); 405 } 406 } |