1 /* 2 * Copyright (c) 1998, 2014, 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 private static final long serialVersionUID = -7577115551785240750L; 97 98 /** A Vector of sources, stored as arbitrary Objects. */ 99 protected Vector<Object> sources = new Vector<Object>(); 100 101 /** A Vector of non-source parameters, stored as arbitrary Objects. */ 102 protected Vector<Object> parameters = new Vector<Object>(); 103 104 /** A dummy constructor. */ 105 public ParameterBlock() {} 106 107 /** 108 * Constructs a <code>ParameterBlock</code> with a given Vector 109 * of sources. 110 * @param sources a <code>Vector</code> of source images 111 */ 112 public ParameterBlock(Vector<Object> sources) { 113 setSources(sources); 114 } 115 116 /** 117 * Constructs a <code>ParameterBlock</code> with a given Vector of sources and 118 * Vector of parameters. 119 * @param sources a <code>Vector</code> of source images 120 * @param parameters a <code>Vector</code> of parameters to be used in the 121 * rendering operation 122 */ 123 public ParameterBlock(Vector<Object> sources, 124 Vector<Object> parameters) 125 { 126 setSources(sources); 127 setParameters(parameters); 128 } 129 130 /** 131 * Creates a shallow copy of a <code>ParameterBlock</code>. The source and 132 * parameter Vectors are copied by reference -- additions or 133 * changes will be visible to both versions. 134 * 135 * @return an Object clone of the <code>ParameterBlock</code>. 136 */ 137 public Object shallowClone() { 138 try { 139 return super.clone(); 140 } catch (Exception e) { 141 // We can't be here since we implement Cloneable. 142 return null; 143 } 144 } 145 146 /** 147 * Creates a copy of a <code>ParameterBlock</code>. The source and parameter 148 * Vectors are cloned, but the actual sources and parameters are 149 * copied by reference. This allows modifications to the order 150 * and number of sources and parameters in the clone to be invisible 151 * to the original <code>ParameterBlock</code>. Changes to the shared sources or 152 * parameters themselves will still be visible. 153 * 154 * @return an Object clone of the <code>ParameterBlock</code>. 155 */ 156 public Object clone() { 157 ParameterBlock theClone; 158 159 try { 160 theClone = (ParameterBlock) super.clone(); 161 } catch (Exception e) { 162 // We can't be here since we implement Cloneable. 163 return null; 164 } 165 166 if (sources != null) { 167 theClone.setSources((Vector)sources.clone()); 168 } 169 if (parameters != null) { 170 theClone.setParameters((Vector)parameters.clone()); 171 } 172 return (Object) theClone; 173 } 174 175 /** 176 * Adds an image to end of the list of sources. The image is 177 * stored as an object in order to allow new node types in the 178 * future. 179 * 180 * @param source an image object to be stored in the source list. 181 * @return a new <code>ParameterBlock</code> containing the specified 182 * <code>source</code>. 183 */ 184 public ParameterBlock addSource(Object source) { 185 sources.addElement(source); 186 return this; 187 } 188 189 /** 190 * Returns a source as a general Object. The caller must cast it into 191 * an appropriate type. 192 * 193 * @param index the index of the source to be returned. 194 * @return an <code>Object</code> that represents the source located 195 * at the specified index in the <code>sources</code> 196 * <code>Vector</code>. 197 * @see #setSource(Object, int) 198 */ 199 public Object getSource(int index) { 200 return sources.elementAt(index); 201 } 202 203 /** 204 * Replaces an entry in the list of source with a new source. 205 * If the index lies beyond the current source list, 206 * the list is extended with nulls as needed. 207 * @param source the specified source image 208 * @param index the index into the <code>sources</code> 209 * <code>Vector</code> at which to 210 * insert the specified <code>source</code> 211 * @return a new <code>ParameterBlock</code> that contains the 212 * specified <code>source</code> at the specified 213 * <code>index</code>. 214 * @see #getSource(int) 215 */ 216 public ParameterBlock setSource(Object source, int index) { 217 int oldSize = sources.size(); 218 int newSize = index + 1; 219 if (oldSize < newSize) { 220 sources.setSize(newSize); 221 } 222 sources.setElementAt(source, index); 223 return this; 224 } 225 226 /** 227 * Returns a source as a <code>RenderedImage</code>. This method is 228 * a convenience method. 229 * An exception will be thrown if the source is not a RenderedImage. 230 * 231 * @param index the index of the source to be returned 232 * @return a <code>RenderedImage</code> that represents the source 233 * image that is at the specified index in the 234 * <code>sources</code> <code>Vector</code>. 235 */ 236 public RenderedImage getRenderedSource(int index) { 237 return (RenderedImage) sources.elementAt(index); 238 } 239 240 /** 241 * Returns a source as a RenderableImage. This method is a 242 * convenience method. 243 * An exception will be thrown if the sources is not a RenderableImage. 244 * 245 * @param index the index of the source to be returned 246 * @return a <code>RenderableImage</code> that represents the source 247 * image that is at the specified index in the 248 * <code>sources</code> <code>Vector</code>. 249 */ 250 public RenderableImage getRenderableSource(int index) { 251 return (RenderableImage) sources.elementAt(index); 252 } 253 254 /** 255 * Returns the number of source images. 256 * @return the number of source images in the <code>sources</code> 257 * <code>Vector</code>. 258 */ 259 public int getNumSources() { 260 return sources.size(); 261 } 262 263 /** 264 * Returns the entire Vector of sources. 265 * @return the <code>sources</code> <code>Vector</code>. 266 * @see #setSources(Vector) 267 */ 268 public Vector<Object> getSources() { 269 return sources; 270 } 271 272 /** 273 * Sets the entire Vector of sources to a given Vector. 274 * @param sources the <code>Vector</code> of source images 275 * @see #getSources 276 */ 277 public void setSources(Vector<Object> sources) { 278 this.sources = sources; 279 } 280 281 /** Clears the list of source images. */ 282 public void removeSources() { 283 sources = new Vector(); 284 } 285 286 /** 287 * Returns the number of parameters (not including source images). 288 * @return the number of parameters in the <code>parameters</code> 289 * <code>Vector</code>. 290 */ 291 public int getNumParameters() { 292 return parameters.size(); 293 } 294 295 /** 296 * Returns the entire Vector of parameters. 297 * @return the <code>parameters</code> <code>Vector</code>. 298 * @see #setParameters(Vector) 299 */ 300 public Vector<Object> getParameters() { 301 return parameters; 302 } 303 304 /** 305 * Sets the entire Vector of parameters to a given Vector. 306 * @param parameters the specified <code>Vector</code> of 307 * parameters 308 * @see #getParameters 309 */ 310 public void setParameters(Vector<Object> parameters) { 311 this.parameters = parameters; 312 } 313 314 /** Clears the list of parameters. */ 315 public void removeParameters() { 316 parameters = new Vector(); 317 } 318 319 /** 320 * Adds an object to the list of parameters. 321 * @param obj the <code>Object</code> to add to the 322 * <code>parameters</code> <code>Vector</code> 323 * @return a new <code>ParameterBlock</code> containing 324 * the specified parameter. 325 */ 326 public ParameterBlock add(Object obj) { 327 parameters.addElement(obj); 328 return this; 329 } 330 331 /** 332 * Adds a Byte to the list of parameters. 333 * @param b the byte to add to the 334 * <code>parameters</code> <code>Vector</code> 335 * @return a new <code>ParameterBlock</code> containing 336 * the specified parameter. 337 */ 338 public ParameterBlock add(byte b) { 339 return add(new Byte(b)); 340 } 341 342 /** 343 * Adds a Character to the list of parameters. 344 * @param c the char to add to the 345 * <code>parameters</code> <code>Vector</code> 346 * @return a new <code>ParameterBlock</code> containing 347 * the specified parameter. 348 */ 349 public ParameterBlock add(char c) { 350 return add(new Character(c)); 351 } 352 353 /** 354 * Adds a Short to the list of parameters. 355 * @param s the short to add to the 356 * <code>parameters</code> <code>Vector</code> 357 * @return a new <code>ParameterBlock</code> containing 358 * the specified parameter. 359 */ 360 public ParameterBlock add(short s) { 361 return add(new Short(s)); 362 } 363 364 /** 365 * Adds a Integer to the list of parameters. 366 * @param i the int to add to the 367 * <code>parameters</code> <code>Vector</code> 368 * @return a new <code>ParameterBlock</code> containing 369 * the specified parameter. 370 */ 371 public ParameterBlock add(int i) { 372 return add(new Integer(i)); 373 } 374 375 /** 376 * Adds a Long to the list of parameters. 377 * @param l the long to add to the 378 * <code>parameters</code> <code>Vector</code> 379 * @return a new <code>ParameterBlock</code> containing 380 * the specified parameter. 381 */ 382 public ParameterBlock add(long l) { 383 return add(new Long(l)); 384 } 385 386 /** 387 * Adds a Float to the list of parameters. 388 * @param f the float to add to the 389 * <code>parameters</code> <code>Vector</code> 390 * @return a new <code>ParameterBlock</code> containing 391 * the specified parameter. 392 */ 393 public ParameterBlock add(float f) { 394 return add(new Float(f)); 395 } 396 397 /** 398 * Adds a Double to the list of parameters. 399 * @param d the double to add to the 400 * <code>parameters</code> <code>Vector</code> 401 * @return a new <code>ParameterBlock</code> containing 402 * the specified parameter. 403 */ 404 public ParameterBlock add(double d) { 405 return add(new Double(d)); 406 } 407 408 /** 409 * Replaces an Object in the list of parameters. 410 * If the index lies beyond the current source list, 411 * the list is extended with nulls as needed. 412 * @param obj the parameter that replaces the 413 * parameter at the specified index in the 414 * <code>parameters</code> <code>Vector</code> 415 * @param index the index of the parameter to be 416 * replaced with the specified parameter 417 * @return a new <code>ParameterBlock</code> containing 418 * the specified parameter. 419 */ 420 public ParameterBlock set(Object obj, int index) { 421 int oldSize = parameters.size(); 422 int newSize = index + 1; 423 if (oldSize < newSize) { 424 parameters.setSize(newSize); 425 } 426 parameters.setElementAt(obj, index); 427 return this; 428 } 429 430 /** 431 * Replaces an Object in the list of parameters with a Byte. 432 * If the index lies beyond the current source list, 433 * the list is extended with nulls as needed. 434 * @param b the parameter that replaces the 435 * parameter at the specified index in the 436 * <code>parameters</code> <code>Vector</code> 437 * @param index the index of the parameter to be 438 * replaced with the specified parameter 439 * @return a new <code>ParameterBlock</code> containing 440 * the specified parameter. 441 */ 442 public ParameterBlock set(byte b, int index) { 443 return set(new Byte(b), index); 444 } 445 446 /** 447 * Replaces an Object in the list of parameters with a Character. 448 * If the index lies beyond the current source list, 449 * the list is extended with nulls as needed. 450 * @param c the parameter that replaces the 451 * parameter at the specified index in the 452 * <code>parameters</code> <code>Vector</code> 453 * @param index the index of the parameter to be 454 * replaced with the specified parameter 455 * @return a new <code>ParameterBlock</code> containing 456 * the specified parameter. 457 */ 458 public ParameterBlock set(char c, int index) { 459 return set(new Character(c), index); 460 } 461 462 /** 463 * Replaces an Object in the list of parameters with a Short. 464 * If the index lies beyond the current source list, 465 * the list is extended with nulls as needed. 466 * @param s the parameter that replaces the 467 * parameter at the specified index in the 468 * <code>parameters</code> <code>Vector</code> 469 * @param index the index of the parameter to be 470 * replaced with the specified parameter 471 * @return a new <code>ParameterBlock</code> containing 472 * the specified parameter. 473 */ 474 public ParameterBlock set(short s, int index) { 475 return set(new Short(s), index); 476 } 477 478 /** 479 * Replaces an Object in the list of parameters with an Integer. 480 * If the index lies beyond the current source list, 481 * the list is extended with nulls as needed. 482 * @param i the parameter that replaces the 483 * parameter at the specified index in the 484 * <code>parameters</code> <code>Vector</code> 485 * @param index the index of the parameter to be 486 * replaced with the specified parameter 487 * @return a new <code>ParameterBlock</code> containing 488 * the specified parameter. 489 */ 490 public ParameterBlock set(int i, int index) { 491 return set(new Integer(i), index); 492 } 493 494 /** 495 * Replaces an Object in the list of parameters with a Long. 496 * If the index lies beyond the current source list, 497 * the list is extended with nulls as needed. 498 * @param l the parameter that replaces the 499 * parameter at the specified index in the 500 * <code>parameters</code> <code>Vector</code> 501 * @param index the index of the parameter to be 502 * replaced with the specified parameter 503 * @return a new <code>ParameterBlock</code> containing 504 * the specified parameter. 505 */ 506 public ParameterBlock set(long l, int index) { 507 return set(new Long(l), index); 508 } 509 510 /** 511 * Replaces an Object in the list of parameters with a Float. 512 * If the index lies beyond the current source list, 513 * the list is extended with nulls as needed. 514 * @param f the parameter that replaces the 515 * parameter at the specified index in the 516 * <code>parameters</code> <code>Vector</code> 517 * @param index the index of the parameter to be 518 * replaced with the specified parameter 519 * @return a new <code>ParameterBlock</code> containing 520 * the specified parameter. 521 */ 522 public ParameterBlock set(float f, int index) { 523 return set(new Float(f), index); 524 } 525 526 /** 527 * Replaces an Object in the list of parameters with a Double. 528 * If the index lies beyond the current source list, 529 * the list is extended with nulls as needed. 530 * @param d the parameter that replaces the 531 * parameter at the specified index in the 532 * <code>parameters</code> <code>Vector</code> 533 * @param index the index of the parameter to be 534 * replaced with the specified parameter 535 * @return a new <code>ParameterBlock</code> containing 536 * the specified parameter. 537 */ 538 public ParameterBlock set(double d, int index) { 539 return set(new Double(d), index); 540 } 541 542 /** 543 * Gets a parameter as an object. 544 * @param index the index of the parameter to get 545 * @return an <code>Object</code> representing the 546 * the parameter at the specified index 547 * into the <code>parameters</code> 548 * <code>Vector</code>. 549 */ 550 public Object getObjectParameter(int index) { 551 return parameters.elementAt(index); 552 } 553 554 /** 555 * A convenience method to return a parameter as a byte. An 556 * exception is thrown if the parameter is 557 * <code>null</code> or not a <code>Byte</code>. 558 * 559 * @param index the index of the parameter to be returned. 560 * @return the parameter at the specified index 561 * as a <code>byte</code> value. 562 * @throws ClassCastException if the parameter at the 563 * specified index is not a <code>Byte</code> 564 * @throws NullPointerException if the parameter at the specified 565 * index is <code>null</code> 566 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 567 * is negative or not less than the current size of this 568 * <code>ParameterBlock</code> object 569 */ 570 public byte getByteParameter(int index) { 571 return ((Byte)parameters.elementAt(index)).byteValue(); 572 } 573 574 /** 575 * A convenience method to return a parameter as a char. An 576 * exception is thrown if the parameter is 577 * <code>null</code> or not a <code>Character</code>. 578 * 579 * @param index the index of the parameter to be returned. 580 * @return the parameter at the specified index 581 * as a <code>char</code> value. 582 * @throws ClassCastException if the parameter at the 583 * specified index is not a <code>Character</code> 584 * @throws NullPointerException if the parameter at the specified 585 * index is <code>null</code> 586 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 587 * is negative or not less than the current size of this 588 * <code>ParameterBlock</code> object 589 */ 590 public char getCharParameter(int index) { 591 return ((Character)parameters.elementAt(index)).charValue(); 592 } 593 594 /** 595 * A convenience method to return a parameter as a short. An 596 * exception is thrown if the parameter is 597 * <code>null</code> or not a <code>Short</code>. 598 * 599 * @param index the index of the parameter to be returned. 600 * @return the parameter at the specified index 601 * as a <code>short</code> value. 602 * @throws ClassCastException if the parameter at the 603 * specified index is not a <code>Short</code> 604 * @throws NullPointerException if the parameter at the specified 605 * index is <code>null</code> 606 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 607 * is negative or not less than the current size of this 608 * <code>ParameterBlock</code> object 609 */ 610 public short getShortParameter(int index) { 611 return ((Short)parameters.elementAt(index)).shortValue(); 612 } 613 614 /** 615 * A convenience method to return a parameter as an int. An 616 * exception is thrown if the parameter is 617 * <code>null</code> or not an <code>Integer</code>. 618 * 619 * @param index the index of the parameter to be returned. 620 * @return the parameter at the specified index 621 * as a <code>int</code> value. 622 * @throws ClassCastException if the parameter at the 623 * specified index is not a <code>Integer</code> 624 * @throws NullPointerException if the parameter at the specified 625 * index is <code>null</code> 626 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 627 * is negative or not less than the current size of this 628 * <code>ParameterBlock</code> object 629 */ 630 public int getIntParameter(int index) { 631 return ((Integer)parameters.elementAt(index)).intValue(); 632 } 633 634 /** 635 * A convenience method to return a parameter as a long. An 636 * exception is thrown if the parameter is 637 * <code>null</code> or not a <code>Long</code>. 638 * 639 * @param index the index of the parameter to be returned. 640 * @return the parameter at the specified index 641 * as a <code>long</code> value. 642 * @throws ClassCastException if the parameter at the 643 * specified index is not a <code>Long</code> 644 * @throws NullPointerException if the parameter at the specified 645 * index is <code>null</code> 646 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 647 * is negative or not less than the current size of this 648 * <code>ParameterBlock</code> object 649 */ 650 public long getLongParameter(int index) { 651 return ((Long)parameters.elementAt(index)).longValue(); 652 } 653 654 /** 655 * A convenience method to return a parameter as a float. An 656 * exception is thrown if the parameter is 657 * <code>null</code> or not a <code>Float</code>. 658 * 659 * @param index the index of the parameter to be returned. 660 * @return the parameter at the specified index 661 * as a <code>float</code> value. 662 * @throws ClassCastException if the parameter at the 663 * specified index is not a <code>Float</code> 664 * @throws NullPointerException if the parameter at the specified 665 * index is <code>null</code> 666 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 667 * is negative or not less than the current size of this 668 * <code>ParameterBlock</code> object 669 */ 670 public float getFloatParameter(int index) { 671 return ((Float)parameters.elementAt(index)).floatValue(); 672 } 673 674 /** 675 * A convenience method to return a parameter as a double. An 676 * exception is thrown if the parameter is 677 * <code>null</code> or not a <code>Double</code>. 678 * 679 * @param index the index of the parameter to be returned. 680 * @return the parameter at the specified index 681 * as a <code>double</code> value. 682 * @throws ClassCastException if the parameter at the 683 * specified index is not a <code>Double</code> 684 * @throws NullPointerException if the parameter at the specified 685 * index is <code>null</code> 686 * @throws ArrayIndexOutOfBoundsException if <code>index</code> 687 * is negative or not less than the current size of this 688 * <code>ParameterBlock</code> object 689 */ 690 public double getDoubleParameter(int index) { 691 return ((Double)parameters.elementAt(index)).doubleValue(); 692 } 693 694 /** 695 * Returns an array of Class objects describing the types 696 * of the parameters. 697 * @return an array of <code>Class</code> objects. 698 */ 699 public Class [] getParamClasses() { 700 int numParams = getNumParameters(); 701 Class [] classes = new Class[numParams]; 702 int i; 703 704 for (i = 0; i < numParams; i++) { 705 Object obj = getObjectParameter(i); 706 if (obj instanceof Byte) { 707 classes[i] = byte.class; 708 } else if (obj instanceof Character) { 709 classes[i] = char.class; 710 } else if (obj instanceof Short) { 711 classes[i] = short.class; 712 } else if (obj instanceof Integer) { 713 classes[i] = int.class; 714 } else if (obj instanceof Long) { 715 classes[i] = long.class; 716 } else if (obj instanceof Float) { 717 classes[i] = float.class; 718 } else if (obj instanceof Double) { 719 classes[i] = double.class; 720 } else { 721 classes[i] = obj.getClass(); 722 } 723 } 724 725 return classes; 726 } 727 }