Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2000, 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.input;
027
028import javafx.event.EventTarget;
029import javafx.event.EventType;
030
031/**
032 * Scroll event indicates that user performed scrolling by mouse wheel,
033 * track pad, touch screen or other similar device.
034 * <p>
035 * When the scrolling is produced by a touch gesture (such as dragging a finger
036 * over a touch screen), it is surrounded by the {@code SCROLL_STARTED} and 
037 * {@code SCROLL_FINISHED} events. Changing number of involved touch points during
038 * the scrolling is considered a new gesture, so the pair of
039 * {@code SCROLL_FINISHED} and {@code SCROLL_STARTED} notifications is delivered
040 * each time the {@code touchCount} changes. When the scrolling is caused by a mouse
041 * wheel rotation, only a one-time {@code SCROLL} event is delivered, without
042 * the started/finished surroundings. If scrolling inertia is active on the
043 * given platform, some {@code SCROLL} events with {@code isInertia()} returning
044 * {@code true} can come after {@code SCROLL_FINISHED}.
045 * <p>
046 * The event is delivered to the top-most
047 * node picked on the gesture coordinates in time of the gesture start - the
048 * whole gesture is delivered to the same node even if the coordinates change
049 * during the gesture. For mouse wheel rotation the event is delivered to the
050 * top-most node picked on mouse cursor location. The delivery is independent
051 * of current focus owner.
052 * <p>
053 * The event provides two different types of scrolling values: pixel-based and 
054 * character/line-based. The basic {@code deltaX} and {@code deltaY} values 
055 * give reasonable results when used as number of pixels
056 * to scroll (The {@code totalDeltaX} and {@code totalDeltaY} contain the 
057 * cumulative values for the whole gesture, zeros for mouse wheel).
058 * For scrolling text (or other line-based content as tables) the
059 * {@code textDelta} values should be used if they are available. The 
060 * {@code textDeltaXUnits} and {@code textDeltaYUnits} determine how to 
061 * interpret the {@code textDeltaX} and {@code textDeltaY} values. If the 
062 * units are set to {@code NONE}, the text-based values are not available
063 * (not provided by the underlying platform) and the pixel-based values
064 * need to be used.
065 * <p>
066 * As all gestures, scrolling can be direct (performed directly at
067 * the concrete coordinates as on touch screen - the center point among all
068 * the touches is usually used as the gesture coordinates) or indirect (performed
069 * indirectly as on track pad or with mouse - the mouse cursor location
070 * is usually used as the gesture coordinates).
071 * <p>
072 * For example, scrolling a graphical node can be achieved by following code:
073 * <code><pre>
074    node.setOnScroll(new EventHandler<ScrollEvent>() {
075        &#64;Override public void handle(ScrollEvent event) {
076            node.setTranslateX(node.getTranslateX() + event.getDeltaX());
077            node.setTranslateY(node.getTranslateY() + event.getDeltaY());
078        }
079    });
080</pre></code>
081 * <p>
082 * A scroll event handler on text-based component behaving
083 * according to system settings on all platforms should contain following logic:
084 * <code><pre>
085    switch(event.getTextDeltaYUnits()) {
086        case LINES:
087            // scroll about event.getTextDeltaY() lines 
088            break;
089        case PAGES:
090            // scroll about event.getTextDeltaY() pages
091            break;
092        case NONE:
093            // scroll about event.getDeltaY() pixels
094            break;
095    }
096 </pre></code>
097 *
098 * @since 2.2
099 */
100public final class ScrollEvent extends GestureEvent {
101
102    private static final long serialVersionUID = 20121107L;
103
104    /**
105     * Common supertype for all scroll event types.
106     */
107    public static final EventType<ScrollEvent> ANY =
108            new EventType<ScrollEvent> (GestureEvent.ANY, "ANY_SCROLL");
109
110    /**
111     * This event occurs when user performs a scrolling action such as
112     * rotating mouse wheel or dragging a finger over touch screen.
113     */
114    public static final EventType<ScrollEvent> SCROLL =
115            new EventType<ScrollEvent> (ScrollEvent.ANY, "SCROLL");
116
117    /**
118     * This event occurs when a scrolling gesture is detected. It doesn't
119     * occur for mouse wheel scrolling.
120     */
121    public static final EventType<ScrollEvent> SCROLL_STARTED =
122            new EventType<ScrollEvent> (ScrollEvent.ANY, "SCROLL_STARTED");
123
124    /**
125     * This event occurs when a scrolling gesture ends. It doesn't
126     * occur for mouse wheel scrolling.
127     */
128    public static final EventType<ScrollEvent> SCROLL_FINISHED =
129            new EventType<ScrollEvent> (ScrollEvent.ANY, "SCROLL_FINISHED");
130
131    /**
132     * Constructs new ScrollEvent event.
133     * @param source the source of the event. Can be null.
134     * @param target the target of the event. Can be null.
135     * @param eventType The type of the event.
136     * @param x The x with respect to the scene.
137     * @param y The y with respect to the scene.
138     * @param screenX The x coordinate relative to screen.
139     * @param screenY The y coordinate relative to screen.
140     * @param shiftDown true if shift modifier was pressed.
141     * @param controlDown true if control modifier was pressed.
142     * @param altDown true if alt modifier was pressed.
143     * @param metaDown true if meta modifier was pressed.
144     * @param direct true if the event was caused by direct input device. See {@link #isDirect() }
145     * @param inertia if represents inertia of an already finished gesture.
146     * @param deltaX horizontal scroll amount
147     * @param deltaY vertical scroll amount
148     * @param totalDeltaX cumulative horizontal scroll amount
149     * @param totalDeltaY cumulative vertical scroll amount
150     * @param textDeltaXUnits units for horizontal text-based scroll amount
151     * @param textDeltaX horizontal text-based scroll amount
152     * @param textDeltaYUnits units for vertical text-based scroll amount
153     * @param textDeltaY vertical text-based scroll amount
154     * @param touchCount number of touch points
155     * @param pickResult pick result. Can be null, in this case a 2D pick result
156     *                   without any further values is constructed
157     *                   based on the scene coordinates and the target
158     */
159    public ScrollEvent(Object source, EventTarget target,
160            final EventType<ScrollEvent> eventType,
161            double x, double y,
162            double screenX, double screenY,
163            boolean shiftDown,
164            boolean controlDown,
165            boolean altDown,
166            boolean metaDown,
167            boolean direct,
168            boolean inertia,
169            double deltaX, double deltaY,
170            double totalDeltaX, double totalDeltaY,
171            HorizontalTextScrollUnits textDeltaXUnits, double textDeltaX,
172            VerticalTextScrollUnits textDeltaYUnits, double textDeltaY,
173            int touchCount, PickResult pickResult) {
174
175        super(source, target, eventType, x, y, screenX, screenY,
176                shiftDown, controlDown, altDown, metaDown, direct, inertia,
177                pickResult);
178        this.deltaX = deltaX;
179        this.deltaY = deltaY;
180        this.totalDeltaX = totalDeltaX;
181        this.totalDeltaY = totalDeltaY;
182        this.textDeltaXUnits = textDeltaXUnits;
183        this.textDeltaX = textDeltaX;
184        this.textDeltaYUnits = textDeltaYUnits;
185        this.textDeltaY = textDeltaY;
186        this.touchCount = touchCount;
187    }
188
189    /**
190     * Constructs new ScrollEvent event with null source and target
191     * @param eventType The type of the event.
192     * @param x The x with respect to the scene.
193     * @param y The y with respect to the scene.
194     * @param screenX The x coordinate relative to screen.
195     * @param screenY The y coordinate relative to screen.
196     * @param shiftDown true if shift modifier was pressed.
197     * @param controlDown true if control modifier was pressed.
198     * @param altDown true if alt modifier was pressed.
199     * @param metaDown true if meta modifier was pressed.
200     * @param direct true if the event was caused by direct input device. See {@link #isDirect() }
201     * @param inertia if represents inertia of an already finished gesture.
202     * @param deltaX horizontal scroll amount
203     * @param deltaY vertical scroll amount
204     * @param totalDeltaX cumulative horizontal scroll amount
205     * @param totalDeltaY cumulative vertical scroll amount
206     * @param textDeltaXUnits units for horizontal text-based scroll amount
207     * @param textDeltaX horizontal text-based scroll amount
208     * @param textDeltaYUnits units for vertical text-based scroll amount
209     * @param textDeltaY vertical text-based scroll amount
210     * @param touchCount number of touch points
211     * @param pickResult pick result. Can be null, in this case a 2D pick result
212     *                   without any further values is constructed
213     *                   based on the scene coordinates
214     */
215    public ScrollEvent(final EventType<ScrollEvent> eventType,
216            double x, double y,
217            double screenX, double screenY,
218            boolean shiftDown,
219            boolean controlDown,
220            boolean altDown,
221            boolean metaDown,
222            boolean direct,
223            boolean inertia,
224            double deltaX, double deltaY,
225            double gestureDeltaX, double gestureDeltaY,
226            HorizontalTextScrollUnits textDeltaXUnits, double textDeltaX,
227            VerticalTextScrollUnits textDeltaYUnits, double textDeltaY,
228            int touchCount,
229            PickResult pickResult) {
230        this(null, null, eventType, x, y, screenX, screenY, shiftDown, controlDown,
231                altDown, metaDown, direct, inertia, deltaX, deltaY, gestureDeltaX,
232                gestureDeltaY, textDeltaXUnits, textDeltaX, textDeltaYUnits, textDeltaY, 
233                touchCount, pickResult);
234    }
235    
236    
237    private final double deltaX;
238
239    /**
240     * Gets the horizontal scroll amount. This value should be interpreted
241     * as a number of pixels to scroll. When scrolling a text-based content,
242     * the {@code textDeltaX} and {@code textDeltaXUnits} values should be 
243     * considered first.
244     * <p>
245     * The sign of the value is reversed compared to the coordinate system
246     * (when you scroll right, the content actually needs to go left). So the 
247     * returned value can be simply added to the content's {@code X}
248     * coordinate.
249     * 
250     * @return Number of pixels to scroll horizontally.
251     */
252    public double getDeltaX() {
253        return deltaX;
254    }
255
256    private final double deltaY;
257
258    /**
259     * Gets the vertical scroll amount. This value should be interpreted
260     * as a number of pixels to scroll. When scrolling a line-based content,
261     * the {@code textDeltaY} and {@code textDeltaYUnits} values should be 
262     * considered first.
263     * <p>
264     * The sign of the value is reversed compared to the coordinate system
265     * (when you scroll down, the content actually needs to go up). So the 
266     * returned value can be simply added to the content's {@code Y}
267     * coordinate.
268     * 
269     * @return Number of pixels to scroll vertically.
270     */
271    public double getDeltaY() {
272        return deltaY;
273    }
274    
275    private double totalDeltaX;
276
277    /**
278     * Gets the cumulative horizontal scroll amount for the whole gesture.
279     * This value should be interpreted as a number of pixels to scroll
280     * relatively to the state at the beginning of the gesture.
281     * Contains zeros for mouse wheel scrolling.
282     * <p>
283     * The sign of the value is reversed compared to the coordinate system
284     * (when you scroll right, the content actually needs to go left). So the
285     * returned value can be simply added to the content's {@code X}
286     * coordinate.
287     *
288     * @return Number of pixels scrolled horizontally during the gesture
289     */
290    public double getTotalDeltaX() {
291        return totalDeltaX;
292    }
293
294    private final double totalDeltaY;
295
296    /**
297     * Gets the cumulative vertical scroll amount for the whole gesture.
298     * This value should be interpreted as a number of pixels to scroll
299     * relatively to the state at the beginning of the gesture.
300     * Contains zeros for mouse wheel scrolling.
301     * <p>
302     * The sign of the value is reversed compared to the coordinate system
303     * (when you scroll down, the content actually needs to go up). So the
304     * returned value can be simply added to the content's {@code Y}
305     * coordinate.
306     *
307     * @return Number of pixels to scrolled vertically during the gesture
308     */
309    public double getTotalDeltaY() {
310        return totalDeltaY;
311    }
312
313    private final HorizontalTextScrollUnits textDeltaXUnits;
314
315    /**
316     * Gets the horizontal scrolling units for text-based scrolling.
317     * The returned value indicates how to interpret the {@code getTextDeltaX()}
318     * value. If the returned value is {@code NONE}, the text-based
319     * scrolling value is not available and the pixel-based 
320     * {@code getDeltaX()} value needs to be used.
321     * 
322     * @return the horizontal scrolling units for text-based scrolling
323     */
324    public HorizontalTextScrollUnits getTextDeltaXUnits() {
325        return textDeltaXUnits;
326    }
327
328    private final VerticalTextScrollUnits textDeltaYUnits;
329
330    /**
331     * Gets the vertical scrolling units for text-based scrolling.
332     * The returned value indicates how to interpret the {@code getTextDeltaY()}
333     * value. If the returned value is {@code NONE}, the text-based
334     * scrolling value is not available and the pixel-based 
335     * {@code getDeltaY()} value needs to be used.
336     * 
337     * @return the vertical scrolling units for text-based scrolling
338     */
339    public VerticalTextScrollUnits getTextDeltaYUnits() {
340        return textDeltaYUnits;
341    }
342    
343    private final double textDeltaX;
344
345    /**
346     * Gets the horizontal text-based scroll amount. This value should be 
347     * interpreted according to the {@code getTextDeltaXUnits()} value. 
348     * 
349     * @return Number of units to scroll horizontally, zero if the text-based 
350     * horizontal scrolling data is not available {@code getTextDeltaXUnits()}
351     * returns {@code NONE}
352     */
353    public double getTextDeltaX() {
354        return textDeltaX;
355    }
356    
357    private final double textDeltaY;
358
359    /**
360     * Gets the vertical text-based scroll amount. This value should be 
361     * interpreted according to the {@code getTextDeltaYUnits()} value. 
362     * 
363     * @return Number of units to scroll vertically, zero if the text-based 
364     * vertical scrolling data is not available {@code getTextDeltaYUnits()}
365     * returns {@code NONE}
366     */
367    public double getTextDeltaY() {
368        return textDeltaY;
369    }
370
371    private final int touchCount;
372
373    /**
374     * Gets number of touch points that caused this event. For non-touch source
375     * devices as mouse wheel and for inertia events after gesture finish
376     * it returns zero.
377     * @return Number of touch points that caused this event
378     */
379    public int getTouchCount() {
380        return touchCount;
381    }
382
383    /**
384     * Returns a string representation of this {@code ScrollEvent} object.
385     * @return a string representation of this {@code ScrollEvent} object.
386     */ 
387    @Override public String toString() {
388        final StringBuilder sb = new StringBuilder("ScrollEvent [");
389
390        sb.append("source = ").append(getSource());
391        sb.append(", target = ").append(getTarget());
392        sb.append(", eventType = ").append(getEventType());
393        sb.append(", consumed = ").append(isConsumed());
394
395        sb.append(", deltaX = ").append(getDeltaX())
396                .append(", deltaY = ").append(getDeltaY());
397        sb.append(", totalDeltaX = ").append(getTotalDeltaX())
398                .append(", totalDeltaY = ").append(getTotalDeltaY());
399        sb.append(", textDeltaXUnits = ").append(getTextDeltaXUnits())
400                .append(", textDeltaX = ").append(getTextDeltaX());
401        sb.append(", textDeltaYUnits = ").append(getTextDeltaYUnits())
402                .append(", textDeltaY = ").append(getTextDeltaY());
403        sb.append(", touchCount = ").append(getTouchCount());
404        sb.append(", x = ").append(getX()).append(", y = ").append(getY())
405                .append(", z = ").append(getZ());
406        sb.append(isDirect() ? ", direct" : ", indirect");
407
408        if (isInertia()) {
409            sb.append(", inertia");
410        }
411
412        if (isShiftDown()) {
413            sb.append(", shiftDown");
414        }
415        if (isControlDown()) {
416            sb.append(", controlDown");
417        }
418        if (isAltDown()) {
419            sb.append(", altDown");
420        }
421        if (isMetaDown()) {
422            sb.append(", metaDown");
423        }
424        if (isShortcutDown()) {
425            sb.append(", shortcutDown");
426        }
427        sb.append(", pickResult = ").append(getPickResult());
428
429        return sb.append("]").toString();
430    }
431
432    @Override
433    public ScrollEvent copyFor(Object newSource, EventTarget newTarget) {
434        return (ScrollEvent) super.copyFor(newSource, newTarget);
435    }
436
437    /**
438     * Creates a copy of the given event with the given fields substituted.
439     * @param source the new source of the copied event
440     * @param target the new target of the copied event
441     * @param eventType the new eventType
442     * @return the event copy with the fields substituted
443     */
444    public ScrollEvent copyFor(Object newSource, EventTarget newTarget, EventType<ScrollEvent> type) {
445        ScrollEvent e = copyFor(newSource, newTarget);
446        e.eventType = type;
447        return e;
448    }
449
450    @Override
451    public EventType<ScrollEvent> getEventType() {
452        return (EventType<ScrollEvent>) super.getEventType();
453    }
454    
455    /**
456     * Horizontal text-based scrolling units.
457     */
458    public static enum HorizontalTextScrollUnits {
459        /**
460         * The horizontal text-based scrolling data is not available (not
461         * provided by the underlying platform).
462         */
463        NONE,
464        
465        /**
466         * The horizontal text-based scrolling amount is a number of characters
467         * to scroll.
468         */
469        CHARACTERS
470    }
471
472    /**
473     * Vertical text-based scrolling units.
474     */
475    public static enum VerticalTextScrollUnits {
476        /**
477         * The vertical text-based scrolling data is not available (not
478         * provided by the underlying platform).
479         */
480        NONE,
481
482        /**
483         * The vertical text-based scrolling amount is a number of lines
484         * to scroll.
485         */
486        LINES,
487
488        /**
489         * The vertical text-based scrolling amount is a number of pages
490         * to scroll.
491         */
492        PAGES
493    }
494}