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;
027
028import java.net.MalformedURLException;
029import java.net.URL;
030import javafx.scene.image.Image;
031import com.sun.javafx.cursor.CursorFrame;
032import com.sun.javafx.cursor.CursorType;
033import com.sun.javafx.cursor.StandardCursorFrame;
034
035/**
036 * A class to encapsulate the bitmap representation of the mouse cursor.
037 */
038public abstract class Cursor {
039    /**
040     * The default cursor type (gets set if no cursor is defined).
041     */
042    public static final Cursor DEFAULT =
043            new StandardCursor("DEFAULT", CursorType.DEFAULT);
044
045    /**
046     * The crosshair cursor type.
047     */
048    public static final Cursor CROSSHAIR =
049            new StandardCursor("CROSSHAIR", CursorType.CROSSHAIR);
050
051    /**
052     * The text cursor type.
053     */
054    public static final Cursor TEXT =
055            new StandardCursor("TEXT", CursorType.TEXT);
056
057    /**
058     * The wait cursor type.
059     */
060    public static final Cursor WAIT =
061            new StandardCursor("WAIT", CursorType.WAIT);
062
063    /**
064     * The south-west-resize cursor type.
065     */
066    public static final Cursor SW_RESIZE =
067            new StandardCursor("SW_RESIZE", CursorType.SW_RESIZE);
068
069    /**
070     * The south-east-resize cursor type.
071     */
072    public static final Cursor SE_RESIZE =
073            new StandardCursor("SE_RESIZE", CursorType.SE_RESIZE);
074
075    /**
076     * The north-west-resize cursor type.
077     */
078    public static final Cursor NW_RESIZE =
079            new StandardCursor("NW_RESIZE", CursorType.NW_RESIZE);
080
081    /**
082     * The north-east-resize cursor type.
083     */
084    public static final Cursor NE_RESIZE =
085            new StandardCursor("NE_RESIZE", CursorType.NE_RESIZE);
086
087    /**
088     * The north-resize cursor type.
089     */
090    public static final Cursor N_RESIZE =
091            new StandardCursor("N_RESIZE", CursorType.N_RESIZE);
092
093    /**
094     * The south-resize cursor type.
095     */
096    public static final Cursor S_RESIZE =
097            new StandardCursor("S_RESIZE", CursorType.S_RESIZE);
098
099    /**
100     * The west-resize cursor type.
101     */
102    public static final Cursor W_RESIZE =
103            new StandardCursor("W_RESIZE", CursorType.W_RESIZE);
104
105    /**
106     * The east-resize cursor type.
107     */
108    public static final Cursor E_RESIZE =
109            new StandardCursor("E_RESIZE", CursorType.E_RESIZE);
110
111    /**
112     * A cursor with a hand which is open
113     */
114    public static final Cursor OPEN_HAND =
115            new StandardCursor("OPEN_HAND", CursorType.OPEN_HAND);
116
117    /**
118     * A cursor with a hand that is closed, often used when
119     * "grabbing", for example, when panning.
120     */
121    public static final Cursor CLOSED_HAND =
122            new StandardCursor("CLOSED_HAND", CursorType.CLOSED_HAND);
123
124    /**
125     * The hand cursor type, resembling a pointing hand, often
126     * used to indicate that something can be clicked, such as
127     * a hyperlink.
128     */
129    public static final Cursor HAND =
130            new StandardCursor("HAND", CursorType.HAND);
131
132    /**
133     * The move cursor type.
134     */
135    public static final Cursor MOVE =
136            new StandardCursor("MOVE", CursorType.MOVE);
137
138    /**
139     * The disappear cursor type. This is often used when dragging
140     * something, such that when the user releases the mouse, the
141     * item will disappear. On Mac, this is used when dragging items
142     * off a toolbar or in other such situations.
143     */
144    public static final Cursor DISAPPEAR =
145            new StandardCursor("DISAPPEAR", CursorType.DISAPPEAR);
146
147    /**
148     * The horizontal cursor type.
149     */
150    public static final Cursor H_RESIZE =
151            new StandardCursor("H_RESIZE", CursorType.H_RESIZE);
152
153    /**
154     * The vertical cursor type.
155     */
156    public static final Cursor V_RESIZE =
157            new StandardCursor("V_RESIZE", CursorType.V_RESIZE);
158
159    /**
160     * The none cursor type. On platforms that don't support
161     * custom cursors, this will be the same as {@code DEFAULT}.
162     */
163    public static final Cursor NONE =
164            new StandardCursor("NONE", CursorType.NONE);
165
166    private String name = "CUSTOM";
167
168    Cursor() { }
169    Cursor(String name) {
170        this.name = name;
171    }
172
173    abstract CursorFrame getCurrentFrame();
174
175    /**
176     * Activates the cursor. Cursor should be activated to make sure
177     * that the {@code impl_getCurrentFrame} returns up-to date values.
178     */
179    void activate() {
180        // no activation necessary for standard cursors
181    }
182
183    /**
184     * Deactivates the cursor. Cursor should be deactivated, when no longer in
185     * use to make it collectible by GC.
186     */
187    void deactivate() {
188    }
189
190    /**
191     * Returns a string representation for the cursor.
192     * @return a string representation for the cursor.
193     */
194    @Override public String toString() {
195        return name;
196    }
197
198    // PENDING_DOC_REVIEW
199    /**
200     * Returns a cursor for the specified identifier. The identifier can be
201     * either a name of some standard cursor or a valid URL string. If the
202     * identifier names a standard cursor the corresponding cursor is returned.
203     * In the case of a URL string, the method returns a new {@code ImageCursor}
204     * created for that URL.
205     *
206     * @param identifier the cursor identifier
207     * @return the cursor for the identifier
208     * @throws IllegalArgumentException if the cursor identifier is not a
209     *      valid URL string nor any standard cursor name
210     */
211    public static Cursor cursor(final String identifier) {
212        if (identifier == null) {
213            throw new NullPointerException(
214                    "The cursor identifier must not be null");
215        }
216
217        if (isUrl(identifier)) {
218            return new ImageCursor(new Image(identifier));
219        }
220
221        String uName = identifier.toUpperCase();
222        if (uName.equals(DEFAULT.name)) {
223            return DEFAULT;
224        } else if(uName.equals(CROSSHAIR.name)) {
225            return CROSSHAIR;
226        } else if (uName.equals(TEXT.name)) {
227            return TEXT;
228        } else if (uName.equals(WAIT.name)) {
229            return WAIT;
230        } else if (uName.equals(MOVE.name)) {
231            return MOVE;
232        } else if (uName.equals(SW_RESIZE.name)) {
233            return SW_RESIZE;
234        } else if (uName.equals(SE_RESIZE.name)) {
235            return SE_RESIZE;
236        } else if (uName.equals(NW_RESIZE.name)) {
237            return NW_RESIZE;
238        } else if (uName.equals(NE_RESIZE.name)) {
239            return NE_RESIZE;
240        } else if (uName.equals(N_RESIZE.name)) {
241            return N_RESIZE;
242        } else if (uName.equals(S_RESIZE.name)) {
243            return S_RESIZE;
244        } else if (uName.equals(W_RESIZE.name)) {
245            return W_RESIZE;
246        } else if (uName.equals(E_RESIZE.name)) {
247            return E_RESIZE;
248        } else if (uName.equals(OPEN_HAND.name)) {
249            return OPEN_HAND;
250        } else if (uName.equals(CLOSED_HAND.name)) {
251            return CLOSED_HAND;
252        } else if (uName.equals(HAND.name)) {
253            return HAND;
254        } else if (uName.equals(H_RESIZE.name)) {
255            return H_RESIZE;
256        } else if (uName.equals(V_RESIZE.name)) {
257            return V_RESIZE;
258        } else if (uName.equals(DISAPPEAR.name)) {
259            return DISAPPEAR;
260        } else if (uName.equals(NONE.name)) {
261            return NONE;
262        }
263        
264        throw new IllegalArgumentException("Invalid cursor specification");
265    }
266
267    private static boolean isUrl(final String identifier) {
268        try {
269            new URL(identifier);
270        } catch (final MalformedURLException e) {
271            return false;
272        }
273
274        return true;
275    }
276
277    private static final class StandardCursor extends Cursor {
278        private final CursorFrame singleFrame;
279
280        public StandardCursor(final String name, final CursorType type) {
281            super(name);
282            singleFrame = new StandardCursorFrame(type);
283        }
284
285        @Override
286        CursorFrame getCurrentFrame() {
287            return singleFrame;
288        }
289    }
290}