Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2012, 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.layout; 027 028import com.sun.javafx.scene.layout.region.BorderImageSlices; 029import javafx.geometry.Insets; 030import javafx.scene.image.Image; 031 032/** 033 * Defines properties describing how to render an image as the border of 034 * some Region. A BorderImage must have an Image specified (it cannot be 035 * null). The {@code repeatX} and {@code repeatY} properties define how the 036 * image is to be repeated in each direction. The {@code slices} property 037 * defines how to slice up the image such that it can be stretched across 038 * the Region, while the {@code widths} defines the area on the Region to 039 * fill with the border image. Finally, the {@code outsets} define the distance 040 * outward from the edge of the border over which the border extends. The 041 * outsets of the BorderImage contribute to the outsets of the Border, which 042 * in turn contribute to the bounds of the Region. 043 * <p/> 044 * Because the BorderImage is immutable, it can safely be used in any 045 * cache, and can safely be reused among multiple Regions. 046 * <p/> 047 * When applied to a Region with a defined shape, a BorderImage is not drawn. 048 * TODO Should the insets still be applied? 049 */ 050public class BorderImage { 051 /** 052 * The image to be used. This will never be null. If this 053 * image fails to load, then the entire BorderImage will 054 * be skipped at rendering time and will not contribute to 055 * any bounds or other computations. 056 */ 057 final Image image; 058 public final Image getImage() { return image; } 059 060 /** 061 * Indicates in what manner (if at all) the border image 062 * is to be repeated along the x-axis of the region. If not specified, 063 * the default value is STRETCH. 064 */ 065 final BorderRepeat repeatX; 066 public final BorderRepeat getRepeatX() { return repeatX; } 067 068 /** 069 * Indicates in what manner (if at all) the border image 070 * is to be repeated along the y-axis of the region. If not specified, 071 * the default value is STRETCH. 072 */ 073 final BorderRepeat repeatY; 074 public final BorderRepeat getRepeatY() { return repeatY; } 075 076 /** 077 * The widths of the border on each side. These can be defined 078 * as either to be absolute widths or percentages of the size of 079 * the Region, {@see BorderWidths} for more details. If null, 080 * this will default to being 1 pixel wide. 081 */ 082 final BorderWidths widths; 083 public final BorderWidths getWidths() { return widths; } 084 085 /** 086 * Defines the slices of the image. JavaFX uses a 4-slice scheme where 087 * the slices each divide up an image into 9 patches. The top-left patch 088 * defines the top-left corner of the border. The top patch defines the top 089 * border and the image making up this patch is stretched horizontally 090 * (or whatever is defined for repeatX) to fill all the required space. The 091 * top-right patch goes in the top-right corner, and the right patch is 092 * stretched vertically (or whatever is defined for repeatY) to fill all the 093 * required space. And so on. The center patch is stretched (or whatever is 094 * defined for repeatX, repeatY) in each dimension. By default the center is 095 * omitted (ie: not drawn), although a BorderImageSlices value of {@code true} 096 * for the {@code filled} property will cause the center to be drawn. A 097 * default value for this property will result in BorderImageSlices.DEFAULT, which 098 * is a border-image-slice of 100% 099 * @see <a href="http://www.w3.org/TR/css3-background/#the-border-image-slice">border-image-slice</a> 100 */ 101 final BorderWidths slices; 102 public final BorderWidths getSlices() { return slices; } 103 104 /** 105 * Specifies whether or not the center patch (as defined by the left, right, top, and bottom slices) 106 * should be drawn. 107 */ 108 final boolean filled; 109 public final boolean isFilled() { return filled; } 110 111 /** 112 * The insets of the BorderImage define where the border should be positioned 113 * relative to the edge of the Region. This value will never be null. 114 */ 115 final Insets insets; 116 public final Insets getInsets() { return insets; } 117 118 // These two are used by Border to compute the insets and outsets of the border 119 final Insets innerEdge; 120 final Insets outerEdge; 121 122 /** 123 * A cached hash code for faster secondary usage. It is expected 124 * that BorderImage will be pulled from a cache in many cases. 125 */ 126 private final int hash; 127 128 /** 129 * Creates a new BorderImage. The image must be specified or a NullPointerException will 130 * be thrown. 131 * 132 * @param image The image to use. This must not be null. 133 * @param widths The widths of the border in each dimension. A null value results in Insets.EMPTY. 134 * @param insets The insets at which to place the border relative to the region. 135 * A null value results in Insets.EMPTY. 136 * @param slices The slices for the image. If null, defaults to BorderImageSlices.DEFAULT 137 * @param repeatX The repeat value for the border image in the x direction. If null, defaults to STRETCH. 138 * @param repeatY The repeat value for the border image in the y direction. If null, defaults to the same 139 * value as repeatX. 140 */ 141 public BorderImage( 142 Image image, BorderWidths widths, Insets insets, BorderWidths slices, boolean filled, 143 BorderRepeat repeatX, BorderRepeat repeatY) { 144 if (image == null) throw new NullPointerException("Image cannot be null"); 145 this.image = image; 146 this.widths = widths == null ? BorderWidths.DEFAULT : widths; 147 this.insets = insets == null ? Insets.EMPTY : insets; 148 this.slices = slices == null ? BorderImageSlices.DEFAULT.widths : slices; 149 this.filled = filled; 150 this.repeatX = repeatX == null ? BorderRepeat.STRETCH : repeatX; 151 this.repeatY = repeatY == null ? this.repeatX : repeatY; 152 153 // Compute the inner & outer edge. The outer edge is insets.top, 154 // while the inner edge is insets.top + widths.top 155 outerEdge = new Insets( 156 Math.max(0, -this.insets.getTop()), 157 Math.max(0, -this.insets.getRight()), 158 Math.max(0, -this.insets.getBottom()), 159 Math.max(0, -this.insets.getLeft())); 160 innerEdge = new Insets( 161 this.insets.getTop() + this.widths.getTop(), 162 this.insets.getRight() + this.widths.getRight(), 163 this.insets.getBottom() + this.widths.getBottom(), 164 this.insets.getLeft() + this.widths.getLeft()); 165 166 // Pre-compute the hash code. NOTE: all variables are prefixed with "this" so that we 167 // do not accidentally compute the hash based on the constructor arguments rather than 168 // based on the fields themselves! 169 int result = this.image.hashCode(); 170 result = 31 * result + this.widths.hashCode(); 171 result = 31 * result + this.slices.hashCode(); 172 result = 31 * result + this.repeatX.hashCode(); 173 result = 31 * result + this.repeatY.hashCode(); 174 result = 31 * result + (this.filled ? 1 : 0); 175 hash = result; 176 } 177 178 /** 179 * @inheritDoc 180 */ 181 @Override public boolean equals(Object o) { 182 if (this == o) return true; 183 if (o == null || getClass() != o.getClass()) return false; 184 BorderImage that = (BorderImage) o; 185 if (this.hash != that.hash) return false; 186 if (filled != that.filled) return false; 187 if (!image.equals(that.image)) return false; 188 if (repeatX != that.repeatX) return false; 189 if (repeatY != that.repeatY) return false; 190 if (!slices.equals(that.slices)) return false; 191 if (!widths.equals(that.widths)) return false; 192 193 return true; 194 } 195 196 /** 197 * @inheritDoc 198 */ 199 @Override public int hashCode() { 200 return hash; 201 } 202}