    001    /* ========================================================================
    002     * JCommon : a free general purpose class library for the Java(tm) platform
    003     * ========================================================================
    004     *
    005     * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
    006     *
    007     * Project Info:  http://www.jfree.org/jcommon/index.html
    008     *
    009     * This library is free software; you can redistribute it and/or modify it
    010     * under the terms of the GNU Lesser General Public License as published by
    011     * the Free Software Foundation; either version 2.1 of the License, or
    012     * (at your option) any later version.
    013     *
    014     * This library is distributed in the hope that it will be useful, but
    015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    017     * License for more details.
    018     *
    019     * You should have received a copy of the GNU Lesser General Public
    020     * License along with this library; if not, write to the Free Software
    021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
    022     * USA.
    023     *
    024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
    025     * in the United States and other countries.]
    026     *
    027     * --------------------
    028     * RectangleAnchor.java
    029     * --------------------
    030     * (C) Copyright 2003-2005, by Object Refinery Limited.
    031     *
    032     * Original Author:  David Gilbert (for Object Refinery Limited);
    033     * Contributor(s):   -;
    034     *
    035     * $Id: RectangleAnchor.java,v 1.6 2005/10/18 13:18:34 mungady Exp $
    036     *
    037     * Changes:
    038     * --------
    039     * 31-Oct-2003 (DG);
    040     * 01-Apr-2004 : Changed java.awt.geom.Dimension2D to org.jfree.ui.Size2D
    041     *               because of JDK bug 4976448 which persists on JDK 1.3.1 (DG);
    042     * 21-Jan-2005 : Changed return type of coordinates() method (DG);
    043     *
    044     */
    045
    046    package org.jfree.ui;
    047
    048    import java.awt.geom.Point2D;
    049    import java.awt.geom.Rectangle2D;
    050    import java.io.ObjectStreamException;
    051    import java.io.Serializable;
    052
    053    /**
    054     * Used to indicate an anchor point for a rectangle.
    055     *
    056     * @author David Gilbert
    057     */
    058    public final class RectangleAnchor implements Serializable {
    059
    060        /** For serialization. */
    061        private static final long serialVersionUID = -2457494205644416327L;
    062
    063        /** Center. */
    064        public static final RectangleAnchor CENTER
    065            = new RectangleAnchor("RectangleAnchor.CENTER");
    066
    067        /** Top. */
    068        public static final RectangleAnchor TOP
    069            = new RectangleAnchor("RectangleAnchor.TOP");
    070
    071        /** Top-Left. */
    072        public static final RectangleAnchor TOP_LEFT
    073            = new RectangleAnchor("RectangleAnchor.TOP_LEFT");
    074
    075        /** Top-Right. */
    076        public static final RectangleAnchor TOP_RIGHT
    077            = new RectangleAnchor("RectangleAnchor.TOP_RIGHT");
    078
    079        /** Bottom. */
    080        public static final RectangleAnchor BOTTOM
    081            = new RectangleAnchor("RectangleAnchor.BOTTOM");
    082
    083        /** Bottom-Left. */
    084        public static final RectangleAnchor BOTTOM_LEFT
    085            = new RectangleAnchor("RectangleAnchor.BOTTOM_LEFT");
    086
    087        /** Bottom-Right. */
    088        public static final RectangleAnchor BOTTOM_RIGHT
    089            = new RectangleAnchor("RectangleAnchor.BOTTOM_RIGHT");
    090
    091        /** Left. */
    092        public static final RectangleAnchor LEFT
    093            = new RectangleAnchor("RectangleAnchor.LEFT");
    094
    095        /** Right. */
    096        public static final RectangleAnchor RIGHT
    097            = new RectangleAnchor("RectangleAnchor.RIGHT");
    098
    099        /** The name. */
    100        private String name;
    101
    102        /**
    103         * Private constructor.
    104         *
    105         * @param name  the name.
    106         */
    107        private RectangleAnchor(final String name) {
    108            this.name = name;
    109        }
    110
    111        /**
    112         * Returns a string representing the object.
    113         *
    114         * @return The string.
    115         */
    116        public String toString() {
    117            return this.name;
    118        }
    119
    120        /**
    121         * Returns <code>true</code> if this object is equal to the specified
    122         * object, and <code>false</code> otherwise.
    123         *
    124         * @param obj  the other object (<code>null</code> permitted).
    125         *
    126         * @return A boolean.
    127         */
    128        public boolean equals(final Object obj) {
    129
    130            if (this == obj) {
    131                return true;
    132            }
    133            if (!(obj instanceof RectangleAnchor)) {
    134                return false;
    135            }
    136
    137            final RectangleAnchor order = (RectangleAnchor) obj;
    138            if (!this.name.equals(order.name)) {
    139                return false;
    140            }
    141
    142            return true;
    143        }
    144
    145        /**
    146         * Returns a hash code value for the object.
    147         *
    148         * @return The hashcode
    149         */
    150        public int hashCode() {
    151            return this.name.hashCode();
    152        }
    153
    154        /**
    155         * Returns the (x, y) coordinates of the specified anchor.
    156         *
    157         * @param rectangle  the rectangle.
    158         * @param anchor  the anchor.
    159         *
    160         * @return The (x, y) coordinates.
    161         */
    162        public static Point2D coordinates(final Rectangle2D rectangle,
    163                                          final RectangleAnchor anchor) {
    164            Point2D result = new Point2D.Double();
    165            if (anchor == RectangleAnchor.CENTER) {
    166                result.setLocation(rectangle.getCenterX(), rectangle.getCenterY());
    167            }
    168            else if (anchor == RectangleAnchor.TOP) {
    169                result.setLocation(rectangle.getCenterX(), rectangle.getMinY());
    170            }
    171            else if (anchor == RectangleAnchor.BOTTOM) {
    172                result.setLocation(rectangle.getCenterX(), rectangle.getMaxY());
    173            }
    174            else if (anchor == RectangleAnchor.LEFT) {
    175                result.setLocation(rectangle.getMinX(), rectangle.getCenterY());
    176            }
    177            else if (anchor == RectangleAnchor.RIGHT) {
    178                result.setLocation(rectangle.getMaxX(), rectangle.getCenterY());
    179            }
    180            else if (anchor == RectangleAnchor.TOP_LEFT) {
    181                result.setLocation(rectangle.getMinX(), rectangle.getMinY());
    182            }
    183            else if (anchor == RectangleAnchor.TOP_RIGHT) {
    184                result.setLocation(rectangle.getMaxX(), rectangle.getMinY());
    185            }
    186            else if (anchor == RectangleAnchor.BOTTOM_LEFT) {
    187                result.setLocation(rectangle.getMinX(), rectangle.getMaxY());
    188            }
    189            else if (anchor == RectangleAnchor.BOTTOM_RIGHT) {
    190                result.setLocation(rectangle.getMaxX(), rectangle.getMaxY());
    191            }
    192            return result;
    193        }
    194
    195        /**
    196         * Creates a new rectangle with the specified dimensions that is aligned to
    197         * the given anchor point <code>(anchorX, anchorY)</code>.
    198         *
    199         * @param dimensions  the dimensions (<code>null</code> not permitted).
    200         * @param anchorX  the x-anchor.
    201         * @param anchorY  the y-anchor.
    202         * @param anchor  the anchor (<code>null</code> not permitted).
    203         *
    204         * @return A rectangle.
    205         */
    206        public static Rectangle2D createRectangle(final Size2D dimensions,
    207                                                  final double anchorX,
    208                                                  final double anchorY,
    209                                                  final RectangleAnchor anchor) {
    210            Rectangle2D result = null;
    211            final double w = dimensions.getWidth();
    212            final double h = dimensions.getHeight();
    213            if (anchor == RectangleAnchor.CENTER) {
    214                result = new Rectangle2D.Double(
    215                    anchorX - w / 2.0, anchorY - h / 2.0, w, h
    216                );
    217            }
    218            else if (anchor == RectangleAnchor.TOP) {
    219                result = new Rectangle2D.Double(
    220                    anchorX - w / 2.0, anchorY - h / 2.0, w, h
    221                );
    222            }
    223            else if (anchor == RectangleAnchor.BOTTOM) {
    224                result = new Rectangle2D.Double(
    225                    anchorX - w / 2.0, anchorY - h / 2.0, w, h
    226                );
    227            }
    228            else if (anchor == RectangleAnchor.LEFT) {
    229                result = new Rectangle2D.Double(
    230                    anchorX, anchorY - h / 2.0, w, h
    231                );
    232            }
    233            else if (anchor == RectangleAnchor.RIGHT) {
    234                result = new Rectangle2D.Double(
    235                    anchorX - w, anchorY - h / 2.0, w, h
    236                );
    237            }
    238            else if (anchor == RectangleAnchor.TOP_LEFT) {
    239                result = new Rectangle2D.Double(
    240                    anchorX - w / 2.0, anchorY - h / 2.0, w, h
    241                );
    242            }
    243            else if (anchor == RectangleAnchor.TOP_RIGHT) {
    244                result = new Rectangle2D.Double(
    245                    anchorX - w / 2.0, anchorY - h / 2.0, w, h
    246                );
    247            }
    248            else if (anchor == RectangleAnchor.BOTTOM_LEFT) {
    249                result = new Rectangle2D.Double(
    250                    anchorX - w / 2.0, anchorY - h / 2.0, w, h
    251                );
    252            }
    253            else if (anchor == RectangleAnchor.BOTTOM_RIGHT) {
    254                result = new Rectangle2D.Double(
    255                    anchorX - w / 2.0, anchorY - h / 2.0, w, h
    256                );
    257            }
    258            return result;
    259        }
    260
    261        /**
    262         * Ensures that serialization returns the unique instances.
    263         *
    264         * @return The object.
    265         *
    266         * @throws ObjectStreamException if there is a problem.
    267         */
    268        private Object readResolve() throws ObjectStreamException {
    269            RectangleAnchor result = null;
    270            if (this.equals(RectangleAnchor.CENTER)) {
    271                result = RectangleAnchor.CENTER;
    272            }
    273            else if (this.equals(RectangleAnchor.TOP)) {
    274                result = RectangleAnchor.TOP;
    275            }
    276            else if (this.equals(RectangleAnchor.BOTTOM)) {
    277                result = RectangleAnchor.BOTTOM;
    278            }
    279            else if (this.equals(RectangleAnchor.LEFT)) {
    280                result = RectangleAnchor.LEFT;
    281            }
    282            else if (this.equals(RectangleAnchor.RIGHT)) {
    283                result = RectangleAnchor.RIGHT;
    284            }
    285            else if (this.equals(RectangleAnchor.TOP_LEFT)) {
    286                result = RectangleAnchor.TOP_LEFT;
    287            }
    288            else if (this.equals(RectangleAnchor.TOP_RIGHT)) {
    289                result = RectangleAnchor.TOP_RIGHT;
    290            }
    291            else if (this.equals(RectangleAnchor.BOTTOM_LEFT)) {
    292                result = RectangleAnchor.BOTTOM_LEFT;
    293            }
    294            else if (this.equals(RectangleAnchor.BOTTOM_RIGHT)) {
    295                result = RectangleAnchor.BOTTOM_RIGHT;
    296            }
    297            return result;
    298        }
    299
    300    }