/*
 * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javafx.scene.paint;

import javafx.beans.NamedArg;
import javafx.scene.image.Image;
import com.sun.javafx.beans.event.AbstractNotifyListener;
import com.sun.javafx.tk.Toolkit;

The ImagePattern class fills a shape with an image pattern. The user may specify the anchor rectangle, which defines the position, width, and height of the image relative to the upper left corner of the shape. If the shape extends out of the anchor rectangle, the image is tiled.

If the proportional variable is set to true (the default) then the anchor rectangle should be specified relative to the unit square (0.0->1.0) and will be stretched across the shape. If the proportional variable is set to false, then the anchor rectangle should be specified in the local coordinate system of the shape and the image will be stretched to fit the anchor rectangle. The anchor rectangle will not be stretched across the shape.

The example below demonstrates the use of the proportional variable. The shapes on the top row use proportional coordinates (the default) to specify the anchor rectangle. The shapes on the bottom row use absolute coordinates. The flower image is stretched to fill the entire triangle shape, while the dot pattern image is tiled within the circle shape.

 import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.scene.paint.ImagePattern; import javafx.scene.shape.Circle; import javafx.scene.shape.Polygon; import javafx.stage.Stage; public class HelloImagePattern extends Application { private static final String flowerURL = "file:flower.png"; private static final String dotsURL = "file:dots.png"; @Override public void start(Stage stage) { stage.setTitle("Image Pattern"); Group root = new Group(); Scene scene = new Scene(root, 600, 450); Image dots = new Image(dotsURL); Image flower = new Image(flowerURL); Polygon p = new Polygon(); p.setLayoutX(10); p.setLayoutY(10); p.getPoints().add(50.0); p.getPoints().add(0.0); p.getPoints().add(100.0); p.getPoints().add(100.0); p.getPoints().add(0.0); p.getPoints().add(100.0); p.setFill(new ImagePattern(flower, 0, 0, 1, 1, true)); root.getChildren().add(p); Polygon p2 = new Polygon(); p2.setLayoutX(10); p2.setLayoutY(120); p2.getPoints().add(50.0); p2.getPoints().add(0.0); p2.getPoints().add(100.0); p2.getPoints().add(100.0); p2.getPoints().add(0.0); p2.getPoints().add(100.0); p2.setFill(new ImagePattern(flower, 0, 0, 100, 100, false)); root.getChildren().add(p2); Circle circ = new Circle(50); circ.setTranslateX(120); circ.setTranslateY(10); circ.setCenterX(50); circ.setCenterY(50); circ.setFill(new ImagePattern(dots, 0.2, 0.2, 0.4, 0.4, true)); root.getChildren().add(circ); Circle circ2 = new Circle(50); circ2.setTranslateX(120); circ2.setTranslateY(10); circ2.setCenterX(50); circ2.setCenterY(50); circ2.setFill(new ImagePattern(dots, 20, 20, 40, 40, false)); root.getChildren().add(circ2); stage.setScene(scene); stage.show(); } 

The code above produces the following:

Since:JavaFX 2.2
/** * <p>The {@code ImagePattern} class fills a shape with an image pattern. The * user may specify the anchor rectangle, which defines the position, * width, and height of the image relative to the upper left corner of the * shape. If the shape extends out of the anchor rectangle, the image is tiled. * </p> * * <p>If the {@code proportional} variable is set to true (the default) * then the anchor rectangle should be specified relative to the unit * square (0.0-&gt;1.0) and will be stretched across the shape. * If the {@code proportional} variable is set to false, then the anchor * rectangle should be specified in the local coordinate system of the shape * and the image will be stretched to fit the anchor rectangle. The anchor * rectangle will not be stretched across the shape.</p> * * <p>The example below demonstrates the use of the {@code proportional} * variable. The shapes on the top row use proportional coordinates * (the default) to specify the anchor rectangle. The shapes on the * bottom row use absolute coordinates. The flower image is stretched * to fill the entire triangle shape, while the dot pattern image is tiled * within the circle shape.</p> * <pre><code> import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.scene.paint.ImagePattern; import javafx.scene.shape.Circle; import javafx.scene.shape.Polygon; import javafx.stage.Stage; public class HelloImagePattern extends Application { private static final String flowerURL = "file:flower.png"; private static final String dotsURL = "file:dots.png"; {@literal @Override public void start(Stage stage)} { stage.setTitle("Image Pattern"); Group root = new Group(); Scene scene = new Scene(root, 600, 450); Image dots = new Image(dotsURL); Image flower = new Image(flowerURL); Polygon p = new Polygon(); p.setLayoutX(10); p.setLayoutY(10); p.getPoints().add(50.0); p.getPoints().add(0.0); p.getPoints().add(100.0); p.getPoints().add(100.0); p.getPoints().add(0.0); p.getPoints().add(100.0); p.setFill(new ImagePattern(flower, 0, 0, 1, 1, true)); root.getChildren().add(p); Polygon p2 = new Polygon(); p2.setLayoutX(10); p2.setLayoutY(120); p2.getPoints().add(50.0); p2.getPoints().add(0.0); p2.getPoints().add(100.0); p2.getPoints().add(100.0); p2.getPoints().add(0.0); p2.getPoints().add(100.0); p2.setFill(new ImagePattern(flower, 0, 0, 100, 100, false)); root.getChildren().add(p2); Circle circ = new Circle(50); circ.setTranslateX(120); circ.setTranslateY(10); circ.setCenterX(50); circ.setCenterY(50); circ.setFill(new ImagePattern(dots, 0.2, 0.2, 0.4, 0.4, true)); root.getChildren().add(circ); Circle circ2 = new Circle(50); circ2.setTranslateX(120); circ2.setTranslateY(10); circ2.setCenterX(50); circ2.setCenterY(50); circ2.setFill(new ImagePattern(dots, 20, 20, 40, 40, false)); root.getChildren().add(circ2); stage.setScene(scene); stage.show(); } </code></pre> * <p>The code above produces the following:</p> * <p><img src="doc-files/ImagePattern.png" alt="A visual rendering of the * HelloImagePattern example"></p> * * @since JavaFX 2.2 */
public final class ImagePattern extends Paint { private Image image;
Gets the image to be used as a paint.
Returns:Image to be used as a paint.
/** * Gets the image to be used as a paint. * * @return Image to be used as a paint. */
public final Image getImage() { return image; } private double x;
Gets the x origin of the anchor rectangle.
@defaultValue0.0
Returns:The x origin of the anchor rectangle.
/** * Gets the x origin of the anchor rectangle. * * @defaultValue 0.0 * @return The x origin of the anchor rectangle. */
public final double getX() { return x; } private double y;
Gets the y origin of the anchor rectangle.
@defaultValue0.0
Returns:The y origin of the anchor rectangle.
/** * Gets the y origin of the anchor rectangle. * * @defaultValue 0.0 * @return The y origin of the anchor rectangle. */
public final double getY() { return y; } private double width = 1f;
Gets the width of the anchor rectangle.
@defaultValue1.0
Returns:The width of the anchor rectangle.
/** * Gets the width of the anchor rectangle. * * @defaultValue 1.0 * @return The width of the anchor rectangle. */
public final double getWidth() { return width; } private double height = 1f;
Gets the height of the anchor rectangle.
@defaultValue1.0
Returns:The height of the anchor rectangle.
/** * Gets the height of the anchor rectangle. * * @defaultValue 1.0 * @return The height of the anchor rectangle. */
public final double getHeight() { return height; } private boolean proportional = true;
Gets a boolean that indicates whether start and end locations are proportional or absolute. If this flag is true, the two end points are defined in a coordinate space where coordinates in the range [0..1] are scaled to map onto the bounds of the shape that the pattern fills. If this flag is false, then the coordinates are specified in the local coordinate system of the node.
@defaultValuetrue
Returns:boolean that is true if this paint is proportional.
/** * Gets a boolean that indicates whether start and end locations are * proportional or absolute. If this flag is true, the two end points are * defined in a coordinate space where coordinates in the range * {@code [0..1]} are scaled to map onto the bounds of the shape that the * pattern fills. If this flag is false, then the coordinates are specified * in the local coordinate system of the node. * * @defaultValue true * @return boolean that is true if this paint is proportional. */
public final boolean isProportional() { return proportional; } @Override public final boolean isOpaque() { // We only ever have Prism as our painting system these days, so we can just // cast this platformPaint to a prism paint type and check for isOpaque. // It would be better to change the type on platformPaint accordingly and // ditch the cast. return ((com.sun.prism.paint.ImagePattern)acc_getPlatformPaint()).isOpaque(); } private Object platformPaint;
Creates a new instance of ImagePattern from the specified image. Default values are used for all other parameters.
Params:
  • image – the image to be used as the paint.
Throws:
/** * Creates a new instance of ImagePattern from the specified image. Default * values are used for all other parameters. * * @param image the image to be used as the paint. * @throws NullPointerException if the image is null. * @throws IllegalArgumentException if image is not done loading, * that is if progress is &lt; 1. */
public ImagePattern(@NamedArg("image") Image image) { if (image == null) { throw new NullPointerException("Image must be non-null."); } else if (image.getProgress() < 1.0) { throw new IllegalArgumentException("Image not yet loaded"); } this.image = image; }
Creates a new instance of ImagePattern.
Params:
  • image – the image to be used as the paint.
  • x – the x origin of the anchor rectangle.
  • y – the y origin of the anchor rectangle.
  • width – the width of the anchor rectangle.
  • height – the height of the anchor rectangle.
  • proportional – whether the coordinates are proportional to the shape which ImagePattern fills
Throws:
/** * Creates a new instance of ImagePattern. * * @param image the image to be used as the paint. * @param x the x origin of the anchor rectangle. * @param y the y origin of the anchor rectangle. * @param width the width of the anchor rectangle. * @param height the height of the anchor rectangle. * @param proportional whether the coordinates are proportional * to the shape which ImagePattern fills * @throws NullPointerException if the image is null. * @throws IllegalArgumentException if image is not done loading, * that is if progress is &lt; 1. */
public ImagePattern(@NamedArg("image") Image image, @NamedArg("x") double x, @NamedArg("y") double y, @NamedArg("width") double width, @NamedArg("height") double height, @NamedArg("proportional") boolean proportional) { if (image == null) { throw new NullPointerException("Image must be non-null."); } else if (image.getProgress() < 1.0) { throw new IllegalArgumentException("Image not yet loaded"); } this.image = image; this.x = x; this.y = y; this.width = width; this.height = height; this.proportional = proportional; } @Override boolean acc_isMutable() { return Toolkit.getImageAccessor().isAnimation(image); } @Override void acc_addListener(AbstractNotifyListener platformChangeListener) { Toolkit.getImageAccessor().getImageProperty(image) .addListener(platformChangeListener); } @Override void acc_removeListener(AbstractNotifyListener platformChangeListener) { Toolkit.getImageAccessor().getImageProperty(image) .removeListener(platformChangeListener); } @Override Object acc_getPlatformPaint() { if (acc_isMutable() || platformPaint == null) { platformPaint = Toolkit.getToolkit().getPaint(this); assert platformPaint != null; } return platformPaint; } }