Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2011, 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
028/**
029 * Defines widths for four components (top, right, bottom, and left).
030 * Each width is defined as a non-negative
031 * value. This value might be interpreted either as an literal value, or as a
032 * percentage of the width or height of the Region, depending on the values
033 * for {@code topAsPercentage}, {@code rightAsPercentage}, {@code bottomAsPercentage},
034 * {@code leftAsPercentage}. The only allowable negative value for top, right,
035 * bottom, and left is {@code AUTO}.
036 * <p/>
037 * Because the BorderWidths is immutable, it can safely be used in any
038 * cache, and can safely be reused among multiple Regions.
039 */
040public final class BorderWidths {
041    /**
042     * When used by a BorderStroke, the value of AUTO is interpreted as the
043     * value of {@link BorderStroke#MEDIUM} for the corresponding side. When
044     * used with a BorderImage, the value of AUTO means to read the corresponding
045     * value from the BorderStroke(s), and not to specify it manually.
046     */
047    public static final double AUTO = -1;
048
049    /**
050     * The default BorderWidths that is used by a BorderImage when null is specified. This
051     * width is a single 1 pixel top, right, bottom, and left, all interpreted as literal values.
052     */
053    public static final BorderWidths DEFAULT = new BorderWidths(1, 1, 1, 1, false, false, false, false);
054
055    /**
056     * An empty set of widths, such that all values are 0 and are literal values.
057     */
058    public static final BorderWidths EMPTY = new BorderWidths(0, 0, 0, 0, false, false, false, false);
059
060    /**
061     * A set of widths representing 100% on each side.
062     */
063    public static final BorderWidths FULL = new BorderWidths(1d, 1d, 1d, 1d, true, true, true, true);
064
065
066    /**
067     * A non-negative value (with the exception of {@link #AUTO}) indicating the border
068     * thickness on the top of the border. This value can be a literal value, or can be
069     * treated as a percentage, based on the value of the
070     * {@link #isTopAsPercentage() topAsPercentage} property.
071     */
072    final double top;
073    public final double getTop() { return top; }
074
075    /**
076     * The non-negative value (with the exception of {@link #AUTO}) indicating the border
077     * thickness on the right of the border. This value can be a literal value, or can be
078     * treated as a percentage, based on the value of the
079     * {@link #isRightAsPercentage() rightAsPercentage} property.
080     */
081    final double right;
082    public final double getRight() { return right; }
083
084    /**
085     * The non-negative value (with the exception of {@link #AUTO}) indicating the border
086     * thickness on the bottom of the border. This value can be a literal value, or can be
087     * treated as a percentage, based on the value of the
088     * {@link #isBottomAsPercentage() bottomAsPercentage} property.
089     */
090    final double bottom;
091    public final double getBottom() { return bottom; }
092
093    /**
094     * The non-negative value (with the exception of {@link #AUTO}) indicating the border
095     * thickness on the left of the border. This value can be an literal value, or can be
096     * treated as a percentage, based on the value of the
097     * {@link #isLeftAsPercentage() leftAsPercentage} property.
098     */
099    final double left;
100    public final double getLeft() { return left; }
101
102    /**
103     * Specifies whether the {@link #getTop() top} property should be interpreted as a percentage ({@code true})
104     * of the region height or not ({@code false}).
105     */
106    final boolean topAsPercentage;
107    public final boolean isTopAsPercentage() { return topAsPercentage; }
108
109    /**
110     * Specifies whether the {@link #getRight() right} property should be interpreted as a percentage ({@code true})
111     * of the region width or not ({@code false}).
112     */
113    final boolean rightAsPercentage;
114    public final boolean isRightAsPercentage() { return rightAsPercentage; }
115
116    /**
117     * Specifies whether the {@link #getBottom() bottom} property should be interpreted as a percentage ({@code true})
118     * of the region height or not ({@code false}).
119     */
120    final boolean bottomAsPercentage;
121    public final boolean isBottomAsPercentage() { return bottomAsPercentage; }
122
123    /**
124     * Specifies whether the {@link #getLeft() left} property should be interpreted as a percentage ({@code true})
125     * of the region width or not ({@code false}).
126     */
127    final boolean leftAsPercentage;
128    public final boolean isLeftAsPercentage() { return leftAsPercentage; }
129
130    /**
131     * A cached hash code for faster secondary usage. It is expected
132     * that BorderWidths will be pulled from a cache in many cases.
133     */
134    private final int hash;
135
136    /**
137     * Creates a new BorderWidths using the given width for all four borders,
138     * and treating this width as a literal value, and not a percentage.
139     *
140     * @param width The border width. This cannot be negative.
141     */
142    public BorderWidths(double width) {
143        this(width, width, width, width, false, false, false, false);
144    }
145
146    /**
147     * Creates a new BorderWidths with the specified widths for top, right,
148     * bottom, and left. None of these values may be negative. Each of these
149     * values is interpreted as a literal value, not as a percentage.
150     *
151     * @param top    The thickness of the border on the top. Must be non-negative.
152     * @param right    The thickness of the border on the right. Must be non-negative.
153     * @param bottom    The thickness of the border on the bottom. Must be non-negative.
154     * @param left    The thickness of the border on the left. Must be non-negative.
155     */
156    public BorderWidths(double top, double right, double bottom, double left) {
157        this(top, right, bottom, left, false, false, false, false);
158    }
159
160    /**
161     * Creates a new BorderWidths. None of the values for {@code top}, {@code right}, {@code bottom},
162     * or {@code left} can be non-negative.
163     *
164     * @param top    The thickness of the border on the top. Must be non-negative.
165     * @param right    The thickness of the border on the right. Must be non-negative.
166     * @param bottom    The thickness of the border on the bottom. Must be non-negative.
167     * @param left    The thickness of the border on the left. Must be non-negative.
168     * @param topAsPercentage    Whether the top should be treated as a percentage.
169     * @param rightAsPercentage    Whether the right should be treated as a percentage.
170     * @param bottomAsPercentage    Whether the bottom should be treated as a percentage.
171     * @param leftAsPercentage        Whether the left should be treated as a percentage.
172     */
173    public BorderWidths(
174            double top, double right, double bottom, double left, boolean topAsPercentage,
175            boolean rightAsPercentage, boolean bottomAsPercentage, boolean leftAsPercentage) {
176
177        // As per CSS 3 Spec (4.3), cannot be negative
178        if ((top != AUTO && top < 0) ||
179                (right != AUTO && right < 0) ||
180                (bottom != AUTO && bottom < 0) ||
181                (left != AUTO && left < 0)) {
182            throw new IllegalArgumentException("None of the widths can be < 0");
183        }
184
185        this.top = top;
186        this.right = right;
187        this.bottom = bottom;
188        this.left = left;
189        this.topAsPercentage = topAsPercentage;
190        this.rightAsPercentage = rightAsPercentage;
191        this.bottomAsPercentage = bottomAsPercentage;
192        this.leftAsPercentage = leftAsPercentage;
193
194        // Pre-compute the hash code. NOTE: all variables are prefixed with "this" so that we
195        // do not accidentally compute the hash based on the constructor arguments rather than
196        // based on the fields themselves!
197        int result;
198        long temp;
199        temp = this.top != +0.0d ? Double.doubleToLongBits(this.top) : 0L;
200        result = (int) (temp ^ (temp >>> 32));
201        temp = this.right != +0.0d ? Double.doubleToLongBits(this.right) : 0L;
202        result = 31 * result + (int) (temp ^ (temp >>> 32));
203        temp = this.bottom != +0.0d ? Double.doubleToLongBits(this.bottom) : 0L;
204        result = 31 * result + (int) (temp ^ (temp >>> 32));
205        temp = this.left != +0.0d ? Double.doubleToLongBits(this.left) : 0L;
206        result = 31 * result + (int) (temp ^ (temp >>> 32));
207        result = 31 * result + (this.topAsPercentage ? 1 : 0);
208        result = 31 * result + (this.rightAsPercentage ? 1 : 0);
209        result = 31 * result + (this.bottomAsPercentage ? 1 : 0);
210        result = 31 * result + (this.leftAsPercentage ? 1 : 0);
211        hash = result;
212    }
213
214    /**
215     * @inheritDoc
216     */
217    @Override public boolean equals(Object o) {
218        if (this == o) return true;
219        if (o == null || getClass() != o.getClass()) return false;
220        BorderWidths that = (BorderWidths) o;
221
222        if (this.hash != that.hash) return false;
223        if (Double.compare(that.bottom, bottom) != 0) return false;
224        if (bottomAsPercentage != that.bottomAsPercentage) return false;
225        if (Double.compare(that.left, left) != 0) return false;
226        if (leftAsPercentage != that.leftAsPercentage) return false;
227        if (Double.compare(that.right, right) != 0) return false;
228        if (rightAsPercentage != that.rightAsPercentage) return false;
229        if (Double.compare(that.top, top) != 0) return false;
230        if (topAsPercentage != that.topAsPercentage) return false;
231
232        return true;
233    }
234
235    /**
236     * @inheritDoc
237     */
238    @Override public int hashCode() {
239        return hash;
240    }
241}