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 javafx.scene.image.Image;
029
030/**
031 * Defines properties describing how to render an image as the background to
032 * some {@link Region}. A BackgroundImage must have an Image specified (it cannot be
033 * null). The {@link #getRepeatX() repeatX} and {@link #getRepeatY() repeatY}
034 * properties define how the image is to be repeated in each direction. The
035 * {@link #getPosition() position} property defines how to position the image on the
036 * Region while the {@link #getSize() size} property defines the size of the image
037 * on the Region. For example, the {@code size} might be defined with
038 * {@link javafx.scene.layout.BackgroundSize#isCover() cover = true}, meaning the image
039 * should be stretched to cover the entire rendering surface of the Region.
040 * <p/>
041 * Because the BackgroundImage is immutable, it can safely be used in any
042 * cache, and can safely be reused among multiple Regions.
043 */
044public final class BackgroundImage {
045
046    // TODO we need to attach a listener to the Image such that when the image loads
047    // we cause the Region to repaint (probably the Region itself needs to handle this).
048
049    /**
050     * The image to be used. This will never be null. If this
051     * image fails to load, then the entire BackgroundImage will
052     * be skipped at rendering time.
053     */
054    final Image image;
055    public final Image getImage() { return image; }
056
057    /**
058     * Indicates in what manner (if at all) the background image
059     * is to be repeated along the x-axis of the region. This
060     * will never be null.
061     */
062    final BackgroundRepeat repeatX;
063    public final BackgroundRepeat getRepeatX() { return repeatX; }
064
065    /**
066     * Indicates in what manner (if at all) the background image
067     * is to be repeated along the y-axis of the region. This will
068     * never be null.
069     */
070    final BackgroundRepeat repeatY;
071    public final BackgroundRepeat getRepeatY() { return repeatY; }
072
073    /**
074     * The position of this BackgroundImage relative to the Region. Note that any
075     * position outside the background area of the region will be clipped.
076     */
077    final BackgroundPosition position;
078    public final BackgroundPosition getPosition() { return position; }
079
080    /**
081     * The size of this image relative to the Region.
082     */
083    final BackgroundSize size;
084    public final BackgroundSize getSize() { return size; }
085
086    /**
087     * A cached hash code for faster secondary usage. It is expected
088     * that BackgroundImage will be pulled from a cache in many cases.
089     */
090    private final int hash;
091
092    /**
093     * Creates a new BackgroundImage. The {@code image} must be specified.
094     *
095     * @param image       The image to use. This cannot be null.
096     * @param repeatX     The BackgroundRepeat for the x axis. If null, this value defaults to REPEAT.
097     * @param repeatY     The BackgroundRepeat for the y axis. If null, this value defaults to REPEAT.
098     * @param position    The BackgroundPosition to use. If null, defaults to BackgroundPosition.DEFAULT.
099     * @param size        The BackgroundSize. If null, defaults to BackgroundSize.DEFAULT.
100     */
101    public BackgroundImage(
102            Image image, BackgroundRepeat repeatX, BackgroundRepeat repeatY,
103            BackgroundPosition position, BackgroundSize size)
104    {
105        if (image == null) throw new NullPointerException("Image cannot be null");
106        this.image = image;
107        // As per the CSS 3 Spec (section 3.4): default to REPEAT
108        this.repeatX = repeatX == null ? BackgroundRepeat.REPEAT : repeatX;
109        this.repeatY = repeatY == null ? BackgroundRepeat.REPEAT : repeatY;
110        this.position = position == null ? BackgroundPosition.DEFAULT : position;
111        this.size = size == null ? BackgroundSize.DEFAULT : size;
112
113        // Pre-compute the hash code. NOTE: all variables are prefixed with "this" so that we
114        // do not accidentally compute the hash based on the constructor arguments rather than
115        // based on the fields themselves!
116        int result = this.image.hashCode();
117        result = 31 * result + this.repeatX.hashCode();
118        result = 31 * result + this.repeatY.hashCode();
119        result = 31 * result + this.position.hashCode();
120        result = 31 * result + this.size.hashCode();
121        hash = result;
122    }
123
124    /**
125     * @inheritDoc
126     */
127    @Override public boolean equals(Object o) {
128        if (this == o) return true;
129        if (o == null || getClass() != o.getClass()) return false;
130        BackgroundImage that = (BackgroundImage) o;
131        // Because the hash is cached, this can be very fast
132        if (hash != that.hash) return false;
133        if (!image.equals(that.image)) return false;
134        if (!position.equals(that.position)) return false;
135        if (repeatX != that.repeatX) return false;
136        if (repeatY != that.repeatY) return false;
137        if (!size.equals(that.size)) return false;
138
139        return true;
140    }
141
142    /**
143     * @inheritDoc
144     */
145    @Override public int hashCode() {
146        return hash;
147    }
148}