Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.scene.paint; 027 028import com.sun.javafx.beans.event.AbstractNotifyListener; 029import com.sun.javafx.tk.Toolkit; 030import javafx.scene.image.Image; 031 032/** 033 * <p>The {@code ImagePattern} class fills a shape with an image pattern. The 034 * user may specify the anchor rectangle, which defines the position, 035 * width, and height of the image relative to the upper left corner of the 036 * shape. If the shape extends out of the anchor rectangle, the image is tiled. 037 * </p> 038 * 039 * <p>If the {@code proportional} variable is set to true (the default) 040 * then the anchor rectangle should be specified relative to the unit 041 * square (0.0->1.0) and will be stretched across the shape. 042 * If the {@code proportional} variable is set to false, then the anchor 043 * rectangle should be specified in the local coordinate system of the shape 044 * and the image will be stretched to fit the anchor rectangle. The anchor 045 * rectangle will not be stretched across the shape.</p> 046 * 047 * <p>The example below demonstrates the use of the {@code proportional} 048 * variable. The shapes on the top row use proportional coordinates 049 * (the default) to specify the anchor rectangle. The shapes on the 050 * bottom row use absolute coordinates. The flower image is stretched 051 * to fill the entire triangle shape, while the dot pattern image is tiled 052 * within the circle shape.</p> 053 * 054<pre><code> 055import javafx.scene.Scene; 056import javafx.scene.image.Image; 057import javafx.scene.paint.ImagePattern; 058import javafx.scene.shape.Circle; 059import javafx.scene.shape.Polygon; 060import javafx.stage.Stage; 061 062public class HelloImagePattern extends Application { 063 064 private static final String flowerURL = "file:flower.png"; 065 private static final String dotsURL = "file:dots.png"; 066 067 @Override public void start(Stage stage) { 068 stage.setTitle("Image Pattern"); 069 Group root = new Group(); 070 Scene scene = new Scene(root, 600, 450); 071 072 Image dots = new Image(dotsURL); 073 Image flower = new Image(flowerURL); 074 075 Polygon p = new Polygon(); 076 077 p.setLayoutX(10); 078 p.setLayoutY(10); 079 p.getPoints().add(50.0); 080 p.getPoints().add(0.0); 081 p.getPoints().add(100.0); 082 p.getPoints().add(100.0); 083 p.getPoints().add(0.0); 084 p.getPoints().add(100.0); 085 086 p.setFill(new ImagePattern(flower, 0, 0, 1, 1, true)); 087 088 root.getChildren().add(p); 089 090 Polygon p2 = new Polygon(); 091 092 p2.setLayoutX(10); 093 p2.setLayoutY(120); 094 p2.getPoints().add(50.0); 095 p2.getPoints().add(0.0); 096 p2.getPoints().add(100.0); 097 p2.getPoints().add(100.0); 098 p2.getPoints().add(0.0); 099 p2.getPoints().add(100.0); 100 101 p2.setFill(new ImagePattern(flower, 0, 0, 100, 100, false)); 102 103 root.getChildren().add(p2); 104 105 Circle circ = new Circle(50); 106 circ.setTranslateX(120); 107 circ.setTranslateY(10); 108 circ.setCenterX(50); 109 circ.setCenterY(50); 110 circ.setFill(new ImagePattern(dots, 0.2, 0.2, 0.4, 0.4, true)); 111 112 root.getChildren().add(circ); 113 114 Circle circ2 = new Circle(50); 115 circ2.setTranslateX(120); 116 circ2.setTranslateY(10); 117 circ2.setCenterX(50); 118 circ2.setCenterY(50); 119 circ2.setFill(new ImagePattern(dots, 20, 20, 40, 40, false)); 120 121 root.getChildren().add(circ2); 122 stage.setScene(scene); 123 stage.show(); 124 } 125</pre></code> 126 * <p>The code above produces the following:</p> 127 * <p><img src="doc-files/ImagePattern.png"/></p> 128 * 129 * @since 2.2 130 */ 131public final class ImagePattern extends Paint { 132 133 private Image image; 134 135 /** 136 * Gets the image to be used as a paint. 137 * 138 * @return Image to be used as a paint. 139 */ 140 public final Image getImage() { 141 return image; 142 } 143 144 145 private double x; 146 147 /** 148 * Gets the x origin of the anchor rectangle. 149 * 150 * @defaultValue 0.0 151 * @return The x origin of the anchor rectangle. 152 */ 153 public final double getX() { 154 return x; 155 } 156 157 private double y; 158 159 /** 160 * Gets the y origin of the anchor rectangle. 161 * 162 * @defaultValue 0.0 163 * @return The y origin of the anchor rectangle. 164 */ 165 public final double getY() { 166 return y; 167 } 168 169 170 private double width = 1f; 171 172 /** 173 * Gets the width of the anchor rectangle. 174 * 175 * @defaultValue 1.0 176 * @return The width of the anchor rectangle. 177 */ 178 public final double getWidth() { 179 return width; 180 } 181 182 183 private double height = 1f; 184 185 /** 186 * Gets the height of the anchor rectangle. 187 * 188 * @defaultValue 1.0 189 * @return The height of the anchor rectangle. 190 */ 191 public final double getHeight() { 192 return height; 193 } 194 195 196 private boolean proportional = true; 197 198 /** 199 * Gets a boolean that indicates whether start and end locations are 200 * proportional or absolute. If this flag is true, the two end points are 201 * defined in a coordinate space where coordinates in the range 202 * {@code [0..1]} are scaled to map onto the bounds of the shape that the 203 * pattern fills. If this flag is false, then the coordinates are specified 204 * in the local coordinate system of the node. 205 * 206 * @defaultValue true 207 * @return boolean that is true if this paint is proportional. 208 */ 209 public final boolean isProportional() { 210 return proportional; 211 } 212 213 @Override public final boolean isOpaque() { 214 // RT-24827: isOpaque should return true if the image doesn't have an alpha. 215 // We haven't implemented this support yet, but should! 216 return false; 217 } 218 219 private Object platformPaint; 220 221 /** 222 * Creates a new instance of ImagePattern from the specified image. Default 223 * values are used for all other parameters. 224 * 225 * @param image the image to be used as the paint. 226 * @throws NullPointerException if the image is null. 227 * @throws IllegalArgumentException if image is not done loading, 228 * that is if progress is < 1. 229 */ 230 public ImagePattern(Image image) { 231 if (image == null) { 232 throw new NullPointerException("Image must be non-null."); 233 } else if (image.getProgress() < 1.0) { 234 throw new IllegalArgumentException("Image not yet loaded"); 235 } 236 this.image = image; 237 } 238 239 /** 240 * Creates a new instance of ImagePattern. 241 * 242 * @param image the image to be used as the paint. 243 * @param x the x origin of the anchor rectangle. 244 * @param y the y origin of the anchor rectangle. 245 * @param width the width of the anchor rectangle. 246 * @param height the height of the anchor rectangle. 247 * @param proportional whether the coordinates are proportional 248 * to the shape which ImagePattern fills 249 * @throws NullPointerException if the image is null. 250 * @throws IllegalArgumentException if image is not done loading, 251 * that is if progress is < 1. 252 */ 253 public ImagePattern(Image image, double x, double y, double width, 254 double height, boolean proportional) { 255 256 if (image == null) { 257 throw new NullPointerException("Image must be non-null."); 258 } else if (image.getProgress() < 1.0) { 259 throw new IllegalArgumentException("Image not yet loaded"); 260 } 261 this.image = image; 262 this.x = x; 263 this.y = y; 264 this.width = width; 265 this.height = height; 266 this.proportional = proportional; 267 } 268 269 @Override 270 boolean acc_isMutable() { 271 return Toolkit.getImageAccessor().isAnimation(image); 272 } 273 274 @Override 275 void acc_addListener(AbstractNotifyListener platformChangeListener) { 276 Toolkit.getImageAccessor().getImageProperty(image) 277 .addListener(platformChangeListener); 278 } 279 280 @Override 281 void acc_removeListener(AbstractNotifyListener platformChangeListener) { 282 Toolkit.getImageAccessor().getImageProperty(image) 283 .removeListener(platformChangeListener); 284 } 285 286 @Override Object acc_getPlatformPaint() { 287 if (acc_isMutable() || platformPaint == null) { 288 platformPaint = Toolkit.getToolkit().getPaint(this); 289 } 290 return platformPaint; 291 } 292}