1 /* 2 * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 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 java.awt.image.renderable; 27 import java.awt.image.RenderedImage; 28 import java.io.Serializable; 29 import java.util.Vector; 30 31 /** 32 * A <code>ParameterBlock</code> encapsulates all the information about sources and 33 * parameters (Objects) required by a RenderableImageOp, or other 34 * classes that process images. 35 * 36 * <p> Although it is possible to place arbitrary objects in the 37 * source Vector, users of this class may impose semantic constraints 38 * such as requiring all sources to be RenderedImages or 39 * RenderableImage. <code>ParameterBlock</code> itself is merely a container and 40 * performs no checking on source or parameter types. 41 * 42 * <p> All parameters in a <code>ParameterBlock</code> are objects; convenience 43 * add and set methods are available that take arguments of base type and 44 * construct the appropriate subclass of Number (such as 45 * Integer or Float). Corresponding get methods perform a 46 * downward cast and have return values of base type; an exception 47 * will be thrown if the stored values do not have the correct type. 48 * There is no way to distinguish between the results of 49 * "short s; add(s)" and "add(new Short(s))". 50 * 51 * <p> Note that the get and set methods operate on references. 52 * Therefore, one must be careful not to share references between 53 * <code>ParameterBlock</code>s when this is inappropriate. For example, to create 54 * a new <code>ParameterBlock</code> that is equal to an old one except for an 55 * added source, one might be tempted to write: 56 * 57 * <pre> 58 * ParameterBlock addSource(ParameterBlock pb, RenderableImage im) { 59 * ParameterBlock pb1 = new ParameterBlock(pb.getSources()); 60 * pb1.addSource(im); 61 * return pb1; 62 * } 63 * </pre> 64 * 65 * <p> This code will have the side effect of altering the original 66 * <code>ParameterBlock</code>, since the getSources operation returned a reference 67 * to its source Vector. Both pb and pb1 share their source Vector, 68 * and a change in either is visible to both. 69 * 70 * <p> A correct way to write the addSource function is to clone 71 * the source Vector: 72 * 73 * <pre> 74 * ParameterBlock addSource (ParameterBlock pb, RenderableImage im) { 75 * ParameterBlock pb1 = new ParameterBlock(pb.getSources().clone()); 76 * pb1.addSource(im); 77 * return pb1; 78 * } 79 * </pre> 80 * 81 * <p> The clone method of <code>ParameterBlock</code> has been defined to 82 * perform a clone of both the source and parameter Vectors for 83 * this reason. A standard, shallow clone is available as 84 * shallowClone. 85 * 86 * <p> The addSource, setSource, add, and set methods are 87 * defined to return 'this' after adding their argument. This allows 88 * use of syntax like: 89 * 90 * <pre> 91 * ParameterBlock pb = new ParameterBlock(); 92 * op = new RenderableImageOp("operation", pb.add(arg1).add(arg2)); 93 * </pre> 94 * */ 95 public class ParameterBlock implements Cloneable, Serializable { 96 /** A Vector of sources, stored as arbitrary Objects. */ 97 protected Vector<Object> sources = new Vector<Object>(); 98 99 /** A Vector of non-source parameters, stored as arbitrary Objects. */ 100 protected Vector<Object> parameters = new Vector<Object>(); 101 102 /** A dummy constructor. */ 103 public ParameterBlock() {} 104 105 /** 106 * Constructs a <code>ParameterBlock</code> with a given Vector 107 * of sources. 108 * @param sources a <code>Vector</code> of source images 109 */ 110 public ParameterBlock(Vector<Object> sources) { 111 setSources(sources); 112 } 113 114 /** 115 * Constructs a <code>ParameterBlock</code> with a given Vector of sources and 116 * Vector of parameters. 117 * @param sources a <code>Vector</code> of source images 118 * @param parameters a <code>Vector</code> of parameters to be used in the 119 * rendering operation 120 */ 121 public ParameterBlock(Vector<Object> sources, 122 Vector<Object> parameters) 123 { 124 setSources(sources); 125 setParameters(parameters); 126 } 127 128 /** 129 * Creates a shallow copy of a <code>ParameterBlock</code>. The source and 130 * parameter Vectors are copied by reference -- additions or 131 * changes will be visible to both versions. 132 * 133 * @return an Object clone of the <code>ParameterBlock</code>. 134 */ 135 public Object shallowClone() { 136 try { 137 return super.clone(); 138 } catch (Exception e) { 139 // We can't be here since we implement Cloneable. 140 return null; 141 } 142 } 143 144 /** 145 * Creates a copy of a <code>ParameterBlock</code>. The source and parameter 146 * Vectors are cloned, but the actual sources and parameters are 147 * copied by reference. This allows modifications to the order 148 * and number of sources and parameters in the clone to be invisible 149 * to the original <code>ParameterBlock</code>. Changes to the shared sources or 150 * parameters themselves will still be visible. 151 * 152 * @return an Object clone of the <code>ParameterBlock</code>. 153 */ 154 public Object clone() { 155 ParameterBlock theClone; 156 157 try { 158 theClone = (ParameterBlock) super.clone(); 159 } catch (Exception e) { 160 // We can't be here since we implement Cloneable. 161 return null; 162 } 163 164 if (sources != null) { 165 theClone.setSources((Vector)sources.clone()); 166 } 167 if (parameters != null) { 168 theClone.setParameters((Vector)parameters.clone()); 169 } 170 return (Object) theClone; 171 } 172 173 /** 174 * Adds an image to end of the list of sources. The image is 175 * stored as an object in order to allow new node types in the 176 * future. 177 * 178 * @param source an image object to be stored in the source list. 179 * @return a new <code>ParameterBlock</code> containing the specified 180 * <code>source</code>. 181 */ 182 public ParameterBlock addSource(Object source) { 183 sources.addElement(source); 184 return this; 185 } 186 187 /** 188 * Returns a source as a general Object. The caller must cast it into 189 * an appropriate type. 190 * 191 * @param index the index of the source to be returned. 192 * @return an <code>Object</code> that represents the source located 193 * at the specified index in the <code>sources</code> 194 * <code>Vector</code>. 195 * @see #setSource(Object, int) 196 */ 197 public Object getSource(int index) { 198 return sources.elementAt(index); 199 } 200 201 /** 202 * Replaces an entry in the list of source with a new source. 203 * If the index lies beyond the current source list, 204 * the list is extended with nulls as needed. 205 * @param source the specified source image 206 * @param index the index into the <code>sources</code> 207 * <code>Vector</code> at which to 208 * insert the specified <code>source</code> 209 * @return a new <code>ParameterBlock</code> that contains the 210 * specified <code>source</code> at the specified 211 * <code>index</code>. 212 * @see #getSource(int) 213 */ 214 public ParameterBlock setSource(Object source, int index) { 215 int oldSize = sources.size(); 216 int newSize = index + 1; 217 if (oldSize < newSize) { 218 sources.setSize(newSize); 219 } 220 sources.setElementAt(source, index); 221 return this; 222 } 223 224 /** 225 * Returns a source as a <code>RenderedImage</code>. This method is 226 * a convenience method. 227 * An exception will be thrown if the source is not a RenderedImage. 228 * 229 * @param index the index of the source to be returned 230 * @return a <code>RenderedImage</code> that represents the source 231 * image that is at the specified index in the 232 * <code>sources</code> <code>Vector</code>. 233 */ 234 public RenderedImage getRenderedSource(int index) { 235 return (RenderedImage) sources.elementAt(index); 236 } 237 238 /** 239 * Returns a source as a RenderableImage. This method is a 240 * convenience method. 241 * An exception will be thrown if the sources is not a RenderableImage. 242 * 243 * @param index the index of the source to be returned 244 * @return a <code>RenderableImage</code> that represents the source 245 * image that is at the specified index in the 246 * <code>sources</code> <code>Vector</code>. 247 */ 248 public RenderableImage getRenderableSource(int index) { 249 return (RenderableImage) sources.elementAt(index); 250 } 251 252 /** 253 * Returns the number of source images. 254 * @return the number of source images in the <code>sources</code> 255 * <code>Vector</code>. 256 */ 257 public int getNumSources() { 258 return sources.size(); 259 } 260 261 /** 262 * Returns the entire Vector of sources. 263 * @return the <code>sources</code> <code>Vector</code>. 264 * @see #setSources(Vector) 265 */ 266 public Vector<Object> getSources() { 267 return sources; 268 } 269 270 /** 271 * Sets the entire Vector of sources to a given Vector. 272 * @param sources the <code>Vector</code> of source images 273 * @see #getSources 274 */ 275 public void setSources(Vector<Object> sources) { 276 this.sources = sources; 277 } 278 279 /** Clears the list of source images. */ 280 public void removeSources() { 281 sources = new Vector(); 282 } 283 284 /** 285 * Returns the number of parameters (not including source images). 286 * @return the number of parameters in the <code>parameters</code> 287 * <code>Vector</code>. 288 */ 289 public int getNumParameters() { 290 return parameters.size(); 291 } 292 293 /** 294 * Returns the entire Vector of parameters. 295 * @return the <code>parameters</code> <code>Vector</code>. 296 * @see #setParameters(Vector) 297 */ 298 public Vector<Object> getParameters() { 299 return parameters; 300 } 301 302 /** 303 * Sets the entire Vector of parameters to a given Vector. 304 * @param parameters the specified <code>Vector</code> of 305 * parameters 306 * @see #getParameters 307 */ 308 public void setParameters(Vector<Object> parameters) { 309 this.parameters = parameters; 310 } 311 312 /** Clears the list of parameters. */ 313 public void removeParameters() { 314 parameters = new Vector(); 315 } 316 317 /** 318 * Adds an object to the list of parameters. 319 * @param obj the <code>Object</code> to add to the 320 * <code>parameters</code> <code>Vector</code> 321 * @return a new <code>ParameterBlock</code> containing 322 * the specified parameter. 323 */ 324 public ParameterBlock add(Object obj) { 325 parameters.addElement(obj); 326 return this; 327 } 328 329 /** 330 * Adds a Byte to the list of parameters. 331 * @param b the byte to add to the 332 * <code>parameters</code> <code>Vector</code> 333 * @return a new <code>ParameterBlock</code> containing 334 * the specified parameter. 335 */ 336 public ParameterBlock add(byte b) { 337 return add(new Byte(b)); 338 } 339 340 /** 341 * Adds a Character to the list of parameters. 342 * @param c the char to add to the 343 * <code>parameters</code> <code>Vector</code> 344 * @return a new <code>ParameterBlock</code> containing 345 * the specified parameter. 346 */ 347 public ParameterBlock add(char c) { 348 return add(new Character(c)); 349 } 350 351 /** 352 * Adds a Short to the list of parameters. 353 * @param s the short to add to the 354 * <code>parameters</code> <code>Vector</code> 355 * @return a new <code>ParameterBlock</code> containing 356 * the specified parameter. 357 */ 358 public ParameterBlock add(short s) { 359 return add(new Short(s)); 360 } 361 362 /** 363 * Adds a Integer to the list of parameters. 364 * @param i the int to add to the 365 * <code>parameters</code> <code>Vector</code> 366 * @return a new <code>ParameterBlock</code> containing 367 * the specified parameter. 368 */ 369 public ParameterBlock add(int i) { 370 return add(new Integer(i)); 371 } 372 373 /** 374 * Adds a Long to the list of parameters. 375 * @param l the long to add to the 376 * <code>parameters</code> <code>Vector</code> 377 * @return a new <code>ParameterBlock</code> containing 378 * the specified parameter. 379 */ 380 public ParameterBlock add(long l) { 381 return add(new Long(l)); 382 } 383 384 /** 385 * Adds a Float to the list of parameters. 386 * @param f the float to add to the 387 * <code>parameters</code> <code>Vector</code> 388 * @return a new <code>ParameterBlock</code> containing 389 * the specified parameter. 390 */ 391 public ParameterBlock add(float f) { 392 return add(new Float(f)); 393 } 394 395 /** 396 * Adds a Double to the list of parameters. 397 * @param d the double to add to the 398 * <code>parameters</code> <code>Vector</code> 399 * @return a new <code>ParameterBlock</code> containing 400 * the specified parameter. 401 */ 402 public ParameterBlock add(double d) { 403 return add(new Double(d)); 404 } 405 406 /** 407 * Replaces an Object in the list of parameters. 408 * If the index lies beyond the current source list, 409 * the list is extended with nulls as needed. 410 * @param obj the parameter that replaces the 411 * parameter at the specified index in the 412 * <code>parameters</code> <code>Vector</code> 413 * @param index the index of the parameter to be 414 * replaced with the specified parameter 415 * @return a new <code>ParameterBlock</code> containing 416 * the specified parameter. 417 */ 418 public ParameterBlock set(Object obj, int index) { 419 int oldSize = parameters.size(); 420 int newSize = index + 1; 421 if (oldSize < newSize) { 422 parameters.setSize(newSize); 423 } 424 parameters.setElementAt(obj, index); 425 return this; 426 } 427 428 /** 429 * Replaces an Object in the list of parameters with a Byte. 430 * If the index lies beyond the current source list, 431 * the list is extended with nulls as needed. 432 * @param b the parameter that replaces the 433 * parameter at the specified index in the 434 * <code>parameters</code> <code>Vector</code> 435 * @param index the index of the parameter to be 436 * replaced with the specified parameter 437 * @return a new <code>ParameterBlock</code> containing 438 * the specified parameter. 439 */ 440 public ParameterBlock set(byte b, int index) { 441 return set(new Byte(b), index); 442 } 443 444 /** 445 * Replaces an Object in the list of parameters with a Character. 446 * If the index lies beyond the current source list, 447 * the list is extended with nulls as needed. 448 * @param c the parameter that replaces the 449 * parameter at the specified index in the 450 * <code>parameters</code> <code>Vector</code> 451 * @param index the index of the parameter to be 452 * replaced with the specified parameter 453 * @return a new <code>ParameterBlock</code> containing 454 * the specified parameter. 455 */ 456 public ParameterBlock set(char c, int index) { 457 return set(new Character(c), index); 458 } 459 460 /** 461 * Replaces an Object in the list of parameters with a Short. 462 * If the index lies beyond the current source list, 463 * the list is extended with nulls as needed. 464 * @param s the parameter that replaces the 465 * parameter at the specified index in the 466 * <code>parameters</code> <code>Vector</code> 467 * @param index the index of the parameter to be 468 * replaced with the specified parameter 469 * @return a new <code>ParameterBlock</code> containing 470 * the specified parameter. 471 */ 472 public ParameterBlock set(short s, int index) { 473 return set(new Short(s), index); 474 } 475 476 /** 477 * Replaces an Object in the list of parameters with an Integer. 478 * If the index lies beyond the current source list, 479 * the list is extended with nulls as needed. 480 * @param i the parameter that replaces the 481 * parameter at the specified index in the 482 * <code>parameters</code> <code>Vector</code> 483 * @param index the index of the parameter to be 484 * replaced with the specified parameter 485 * @return a new <code>ParameterBlock</code> containing 486 * the specified parameter. 487 */ 488 public ParameterBlock set(int i, int index) { 489 return set(new Integer(i), index); 490 } 491 492 /** 493 * Replaces an Object in the list of parameters with a Long. 494 * If the index lies beyond the current source list, 495 * the list is extended with nulls as needed. 496 * @param l the parameter that replaces the 497 * parameter at the specified index in the 498 * <code>parameters</code> <code>Vector</code> 499 * @param index the index of the parameter to be 500 * replaced with the specified parameter 501 * @return a new <code>ParameterBlock</code> containing 502 * the specified parameter. 503 */ 504 public ParameterBlock set(long l, int index) { 505 return set(new Long(l), index); 506 } 507 508 /** 509 * Replaces an Object in the list of parameters with a Float. 510 * If the index lies beyond the current source list, 511 * the list is extended with nulls as needed. 512 * @param f the parameter that replaces the 513 * parameter at the specified index in the 514 * <code>parameters</code> <code>Vector</code> 515 * @param index the index of the parameter to be 516 * replaced with the specified parameter 517 * @return a new <code>ParameterBlock</code> containing 518 * the specified parameter. 519 */ 520 public ParameterBlock set(float f, int index) { 521 return set(new Float(f), index); 522 } 523 524 /** 525 * Replaces an Object in the list of parameters with a Double. 526 * If the index lies beyond the current source list, 527 * the list is extended with nulls as needed. 528 * @param d the parameter that replaces the 529 * parameter at the specified index in the 530 * <code>parameters</code> <code>Vector</code> 531 * @param index the index of the parameter to be 532 * replaced with the specified parameter 533 * @return a new <code>ParameterBlock</code> containing 534 * the specified parameter. 535 */ 536 public ParameterBlock set(double d, int index) { 537 return set(new Double(d), index); 538 } 539 540 /** 541 * Gets a parameter as an object. 542 * @param index the index of the parameter to get 543 * @return an <code>Object</code> representing the 544 * the parameter at the specified index 545 * into the <code>parameters</code> 546 * <code>Vector</code>. 547 */ 548 public Object getObjectParameter(int index) { 549 return parameters.elementAt(index); 550 } 551 552 /** 553 * A convenience method to return a parameter as a byte. An 554 * exception is thrown if the parameter is 555 * <code>null</code> or not a <code>Byte</code>. 556 * 557 * @param index the index of the parameter to be returned. 558 * @return the parameter at the specified index 559 * as a <code>byte</code> value. 560 * @throws ClassCastException if the parameter at the 561 * specified index is not a <code>Byte</code> 562 * @throws NullPointerException if the parameter at the specified 563 * index is <code>null</code> 564 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 565 * is negative or not less than the current size of this 566 * <code>ParameterBlock</code> object 567 */ 568 public byte getByteParameter(int index) { 569 return ((Byte)parameters.elementAt(index)).byteValue(); 570 } 571 572 /** 573 * A convenience method to return a parameter as a char. An 574 * exception is thrown if the parameter is 575 * <code>null</code> or not a <code>Character</code>. 576 * 577 * @param index the index of the parameter to be returned. 578 * @return the parameter at the specified index 579 * as a <code>char</code> value. 580 * @throws ClassCastException if the parameter at the 581 * specified index is not a <code>Character</code> 582 * @throws NullPointerException if the parameter at the specified 583 * index is <code>null</code> 584 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 585 * is negative or not less than the current size of this 586 * <code>ParameterBlock</code> object 587 */ 588 public char getCharParameter(int index) { 589 return ((Character)parameters.elementAt(index)).charValue(); 590 } 591 592 /** 593 * A convenience method to return a parameter as a short. An 594 * exception is thrown if the parameter is 595 * <code>null</code> or not a <code>Short</code>. 596 * 597 * @param index the index of the parameter to be returned. 598 * @return the parameter at the specified index 599 * as a <code>short</code> value. 600 * @throws ClassCastException if the parameter at the 601 * specified index is not a <code>Short</code> 602 * @throws NullPointerException if the parameter at the specified 603 * index is <code>null</code> 604 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 605 * is negative or not less than the current size of this 606 * <code>ParameterBlock</code> object 607 */ 608 public short getShortParameter(int index) { 609 return ((Short)parameters.elementAt(index)).shortValue(); 610 } 611 612 /** 613 * A convenience method to return a parameter as an int. An 614 * exception is thrown if the parameter is 615 * <code>null</code> or not an <code>Integer</code>. 616 * 617 * @param index the index of the parameter to be returned. 618 * @return the parameter at the specified index 619 * as a <code>int</code> value. 620 * @throws ClassCastException if the parameter at the 621 * specified index is not a <code>Integer</code> 622 * @throws NullPointerException if the parameter at the specified 623 * index is <code>null</code> 624 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 625 * is negative or not less than the current size of this 626 * <code>ParameterBlock</code> object 627 */ 628 public int getIntParameter(int index) { 629 return ((Integer)parameters.elementAt(index)).intValue(); 630 } 631 632 /** 633 * A convenience method to return a parameter as a long. An 634 * exception is thrown if the parameter is 635 * <code>null</code> or not a <code>Long</code>. 636 * 637 * @param index the index of the parameter to be returned. 638 * @return the parameter at the specified index 639 * as a <code>long</code> value. 640 * @throws ClassCastException if the parameter at the 641 * specified index is not a <code>Long</code> 642 * @throws NullPointerException if the parameter at the specified 643 * index is <code>null</code> 644 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 645 * is negative or not less than the current size of this 646 * <code>ParameterBlock</code> object 647 */ 648 public long getLongParameter(int index) { 649 return ((Long)parameters.elementAt(index)).longValue(); 650 } 651 652 /** 653 * A convenience method to return a parameter as a float. An 654 * exception is thrown if the parameter is 655 * <code>null</code> or not a <code>Float</code>. 656 * 657 * @param index the index of the parameter to be returned. 658 * @return the parameter at the specified index 659 * as a <code>float</code> value. 660 * @throws ClassCastException if the parameter at the 661 * specified index is not a <code>Float</code> 662 * @throws NullPointerException if the parameter at the specified 663 * index is <code>null</code> 664 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 665 * is negative or not less than the current size of this 666 * <code>ParameterBlock</code> object 667 */ 668 public float getFloatParameter(int index) { 669 return ((Float)parameters.elementAt(index)).floatValue(); 670 } 671 672 /** 673 * A convenience method to return a parameter as a double. An 674 * exception is thrown if the parameter is 675 * <code>null</code> or not a <code>Double</code>. 676 * 677 * @param index the index of the parameter to be returned. 678 * @return the parameter at the specified index 679 * as a <code>double</code> value. 680 * @throws ClassCastException if the parameter at the 681 * specified index is not a <code>Double</code> 682 * @throws NullPointerException if the parameter at the specified 683 * index is <code>null</code> 684 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 685 * is negative or not less than the current size of this 686 * <code>ParameterBlock</code> object 687 */ 688 public double getDoubleParameter(int index) { 689 return ((Double)parameters.elementAt(index)).doubleValue(); 690 } 691 692 /** 693 * Returns an array of Class objects describing the types 694 * of the parameters. 695 * @return an array of <code>Class</code> objects. 696 */ 697 public Class [] getParamClasses() { 698 int numParams = getNumParameters(); 699 Class [] classes = new Class[numParams]; 700 int i; 701 702 for (i = 0; i < numParams; i++) { 703 Object obj = getObjectParameter(i); 704 if (obj instanceof Byte) { 705 classes[i] = byte.class; 706 } else if (obj instanceof Character) { 707 classes[i] = char.class; 708 } else if (obj instanceof Short) { 709 classes[i] = short.class; 710 } else if (obj instanceof Integer) { 711 classes[i] = int.class; 712 } else if (obj instanceof Long) { 713 classes[i] = long.class; 714 } else if (obj instanceof Float) { 715 classes[i] = float.class; 716 } else if (obj instanceof Double) { 717 classes[i] = double.class; 718 } else { 719 classes[i] = obj.getClass(); 720 } 721 } 722 723 return classes; 724 } 725 }