1 /*
2 * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package java.awt.event;
27
28 import java.awt.Component;
29
30 /**
31 * An event which indicates that the mouse wheel was rotated in a component.
32 * <P>
33 * A wheel mouse is a mouse which has a wheel in place of the middle button.
34 * This wheel can be rotated towards or away from the user. Mouse wheels are
35 * most often used for scrolling, though other uses are possible.
36 * <P>
37 * A MouseWheelEvent object is passed to every <code>MouseWheelListener</code>
38 * object which registered to receive the "interesting" mouse events using the
39 * component's <code>addMouseWheelListener</code> method. Each such listener
40 * object gets a <code>MouseEvent</code> containing the mouse event.
41 * <P>
42 * Due to the mouse wheel's special relationship to scrolling Components,
43 * MouseWheelEvents are delivered somewhat differently than other MouseEvents.
44 * This is because while other MouseEvents usually affect a change on
45 * the Component directly under the mouse
46 * cursor (for instance, when clicking a button), MouseWheelEvents often have
47 * an effect away from the mouse cursor (moving the wheel while
48 * over a Component inside a ScrollPane should scroll one of the
49 * Scrollbars on the ScrollPane).
50 * <P>
51 * MouseWheelEvents start delivery from the Component underneath the
52 * mouse cursor. If MouseWheelEvents are not enabled on the
53 * Component, the event is delivered to the first ancestor
54 * Container with MouseWheelEvents enabled. This will usually be
55 * a ScrollPane with wheel scrolling enabled. The source
56 * Component and x,y coordinates will be relative to the event's
57 * final destination (the ScrollPane). This allows a complex
58 * GUI to be installed without modification into a ScrollPane, and
59 * for all MouseWheelEvents to be delivered to the ScrollPane for
60 * scrolling.
61 * <P>
62 * Some AWT Components are implemented using native widgets which
63 * display their own scrollbars and handle their own scrolling.
64 * The particular Components for which this is true will vary from
65 * platform to platform. When the mouse wheel is
66 * moved over one of these Components, the event is delivered straight to
67 * the native widget, and not propagated to ancestors.
68 * <P>
69 * Platforms offer customization of the amount of scrolling that
70 * should take place when the mouse wheel is moved. The two most
71 * common settings are to scroll a certain number of "units"
72 * (commonly lines of text in a text-based component) or an entire "block"
73 * (similar to page-up/page-down). The MouseWheelEvent offers
74 * methods for conforming to the underlying platform settings. These
75 * platform settings can be changed at any time by the user. MouseWheelEvents
76 * reflect the most recent settings.
77 * <P>
78 * The <code>MouseWheelEvent</code> class includes methods for
79 * getting the number of "clicks" by which the mouse wheel is rotated.
80 * The {@link #getWheelRotation} method returns the integer number
81 * of "clicks" corresponding to the number of notches by which the wheel was
82 * rotated. In addition to this method, the <code>MouseWheelEvent</code>
83 * class provides the {@link #getPreciseWheelRotation} method which returns
84 * a double number of "clicks" in case a partial rotation occurred.
85 * The {@link #getPreciseWheelRotation} method is useful if a mouse supports
86 * a high-resolution wheel, such as a freely rotating wheel with no
87 * notches. Applications can benefit by using this method to process
88 * mouse wheel events more precisely, and thus, making visual perception
89 * smoother.
90 *
91 * @author Brent Christian
92 * @see MouseWheelListener
93 * @see java.awt.ScrollPane
94 * @see java.awt.ScrollPane#setWheelScrollingEnabled(boolean)
95 * @see javax.swing.JScrollPane
96 * @see javax.swing.JScrollPane#setWheelScrollingEnabled(boolean)
97 * @since 1.4
98 */
99
100 public class MouseWheelEvent extends MouseEvent {
101
102 /**
103 * Constant representing scrolling by "units" (like scrolling with the
104 * arrow keys)
105 *
106 * @see #getScrollType
107 */
108 public static final int WHEEL_UNIT_SCROLL = 0;
109
110 /**
111 * Constant representing scrolling by a "block" (like scrolling
112 * with page-up, page-down keys)
113 *
114 * @see #getScrollType
115 */
116 public static final int WHEEL_BLOCK_SCROLL = 1;
117
118 /**
119 * Indicates what sort of scrolling should take place in response to this
120 * event, based on platform settings. Legal values are:
121 * <ul>
122 * <li> WHEEL_UNIT_SCROLL
123 * <li> WHEEL_BLOCK_SCROLL
124 * </ul>
125 *
126 * @see #getScrollType
127 */
128 int scrollType;
129
130 /**
131 * Only valid for scrollType WHEEL_UNIT_SCROLL.
132 * Indicates number of units that should be scrolled per
133 * click of mouse wheel rotation, based on platform settings.
134 *
135 * @see #getScrollAmount
136 * @see #getScrollType
137 */
138 int scrollAmount;
139
140 /**
141 * Indicates how far the mouse wheel was rotated.
142 *
143 * @see #getWheelRotation
144 */
145 int wheelRotation;
146
147 /**
148 * Indicates how far the mouse wheel was rotated.
149 *
150 * @see #getPreciseWheelRotation
151 */
152 double preciseWheelRotation;
153
154 /*
155 * serialVersionUID
156 */
157
158 private static final long serialVersionUID = 6459879390515399677L;
159
160 /**
161 * Constructs a <code>MouseWheelEvent</code> object with the
162 * specified source component, type, modifiers, coordinates,
163 * scroll type, scroll amount, and wheel rotation.
164 * <p>Absolute coordinates xAbs and yAbs are set to source's location on screen plus
165 * relative coordinates x and y. xAbs and yAbs are set to zero if the source is not showing.
166 * <p>Note that passing in an invalid <code>id</code> results in
167 * unspecified behavior. This method throws an
168 * <code>IllegalArgumentException</code> if <code>source</code>
169 * is <code>null</code>.
170 *
171 * @param source the <code>Component</code> that originated
172 * the event
173 * @param id the integer that identifies the event
174 * @param when a long that gives the time the event occurred
175 * @param modifiers the modifier keys down during event
176 * (shift, ctrl, alt, meta)
177 * @param x the horizontal x coordinate for the mouse location
178 * @param y the vertical y coordinate for the mouse location
179 * @param clickCount the number of mouse clicks associated with event
180 * @param popupTrigger a boolean, true if this event is a trigger for a
181 * popup-menu
182 * @param scrollType the type of scrolling which should take place in
183 * response to this event; valid values are
184 * <code>WHEEL_UNIT_SCROLL</code> and
185 * <code>WHEEL_BLOCK_SCROLL</code>
186 * @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
187 * the number of units to be scrolled
188 * @param wheelRotation the integer number of "clicks" by which the mouse
189 * wheel was rotated
190 *
191 * @throws IllegalArgumentException if <code>source</code> is null
192 * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
193 * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, int, int, boolean, int)
194 */
195 public MouseWheelEvent (Component source, int id, long when, int modifiers,
196 int x, int y, int clickCount, boolean popupTrigger,
197 int scrollType, int scrollAmount, int wheelRotation) {
198
199 this(source, id, when, modifiers, x, y, 0, 0, clickCount,
200 popupTrigger, scrollType, scrollAmount, wheelRotation);
201 }
202
203 /**
204 * Constructs a <code>MouseWheelEvent</code> object with the
205 * specified source component, type, modifiers, coordinates,
206 * absolute coordinates, scroll type, scroll amount, and wheel rotation.
207 * <p>Note that passing in an invalid <code>id</code> results in
208 * unspecified behavior. This method throws an
209 * <code>IllegalArgumentException</code> if <code>source</code>
210 * is <code>null</code>.<p>
211 * Even if inconsistent values for relative and absolute coordinates are
212 * passed to the constructor, the MouseWheelEvent instance is still
213 * created and no exception is thrown.
214 *
215 * @param source the <code>Component</code> that originated
216 * the event
217 * @param id the integer that identifies the event
218 * @param when a long that gives the time the event occurred
219 * @param modifiers the modifier keys down during event
220 * (shift, ctrl, alt, meta)
221 * @param x the horizontal x coordinate for the mouse location
222 * @param y the vertical y coordinate for the mouse location
223 * @param xAbs the absolute horizontal x coordinate for the mouse location
224 * @param yAbs the absolute vertical y coordinate for the mouse location
225 * @param clickCount the number of mouse clicks associated with event
226 * @param popupTrigger a boolean, true if this event is a trigger for a
227 * popup-menu
228 * @param scrollType the type of scrolling which should take place in
229 * response to this event; valid values are
230 * <code>WHEEL_UNIT_SCROLL</code> and
231 * <code>WHEEL_BLOCK_SCROLL</code>
232 * @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
233 * the number of units to be scrolled
234 * @param wheelRotation the integer number of "clicks" by which the mouse
235 * wheel was rotated
236 *
237 * @throws IllegalArgumentException if <code>source</code> is null
238 * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
239 * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, int, int, boolean, int)
240 * @since 1.6
241 */
242 public MouseWheelEvent (Component source, int id, long when, int modifiers,
243 int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger,
244 int scrollType, int scrollAmount, int wheelRotation) {
245
246 this(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount, popupTrigger,
247 scrollType, scrollAmount, wheelRotation, wheelRotation);
248
249 }
250
251
252 /**
253 * Constructs a <code>MouseWheelEvent</code> object with the specified
254 * source component, type, modifiers, coordinates, absolute coordinates,
255 * scroll type, scroll amount, and wheel rotation.
256 * <p>Note that passing in an invalid <code>id</code> parameter results
257 * in unspecified behavior. This method throws an
258 * <code>IllegalArgumentException</code> if <code>source</code> equals
259 * <code>null</code>.
260 * <p>Even if inconsistent values for relative and absolute coordinates
261 * are passed to the constructor, a <code>MouseWheelEvent</code> instance
262 * is still created and no exception is thrown.
263 *
264 * @param source the <code>Component</code> that originated the event
265 * @param id the integer value that identifies the event
266 * @param when a long value that gives the time when the event occurred
267 * @param modifiers the modifier keys down during event
268 * (shift, ctrl, alt, meta)
269 * @param x the horizontal <code>x</code> coordinate for the
270 * mouse location
271 * @param y the vertical <code>y</code> coordinate for the
272 * mouse location
273 * @param xAbs the absolute horizontal <code>x</code> coordinate for
274 * the mouse location
275 * @param yAbs the absolute vertical <code>y</code> coordinate for
276 * the mouse location
277 * @param clickCount the number of mouse clicks associated with the event
278 * @param popupTrigger a boolean value, <code>true</code> if this event is a trigger
279 * for a popup-menu
280 * @param scrollType the type of scrolling which should take place in
281 * response to this event; valid values are
282 * <code>WHEEL_UNIT_SCROLL</code> and
283 * <code>WHEEL_BLOCK_SCROLL</code>
284 * @param scrollAmount for scrollType <code>WHEEL_UNIT_SCROLL</code>,
285 * the number of units to be scrolled
286 * @param wheelRotation the integer number of "clicks" by which the mouse wheel
287 * was rotated
288 * @param preciseWheelRotation the double number of "clicks" by which the mouse wheel
289 * was rotated
290 *
291 * @throws IllegalArgumentException if <code>source</code> is null
292 * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, boolean)
293 * @see MouseEvent#MouseEvent(java.awt.Component, int, long, int, int, int, int, int, int, boolean, int)
294 * @since 1.7
295 */
296 public MouseWheelEvent (Component source, int id, long when, int modifiers,
297 int x, int y, int xAbs, int yAbs, int clickCount, boolean popupTrigger,
298 int scrollType, int scrollAmount, int wheelRotation, double preciseWheelRotation) {
299
300 super(source, id, when, modifiers, x, y, xAbs, yAbs, clickCount,
301 popupTrigger, MouseEvent.NOBUTTON);
302
303 this.scrollType = scrollType;
304 this.scrollAmount = scrollAmount;
305 this.wheelRotation = wheelRotation;
306 this.preciseWheelRotation = preciseWheelRotation;
307
308 }
309
310 /**
311 * Returns the type of scrolling that should take place in response to this
312 * event. This is determined by the native platform. Legal values are:
313 * <ul>
314 * <li> MouseWheelEvent.WHEEL_UNIT_SCROLL
315 * <li> MouseWheelEvent.WHEEL_BLOCK_SCROLL
316 * </ul>
317 *
318 * @return either MouseWheelEvent.WHEEL_UNIT_SCROLL or
319 * MouseWheelEvent.WHEEL_BLOCK_SCROLL, depending on the configuration of
320 * the native platform.
321 * @see java.awt.Adjustable#getUnitIncrement
322 * @see java.awt.Adjustable#getBlockIncrement
323 * @see javax.swing.Scrollable#getScrollableUnitIncrement
324 * @see javax.swing.Scrollable#getScrollableBlockIncrement
325 */
326 public int getScrollType() {
327 return scrollType;
328 }
329
330 /**
331 * Returns the number of units that should be scrolled per
332 * click of mouse wheel rotation.
333 * Only valid if <code>getScrollType</code> returns
334 * <code>MouseWheelEvent.WHEEL_UNIT_SCROLL</code>
335 *
336 * @return number of units to scroll, or an undefined value if
337 * <code>getScrollType</code> returns
338 * <code>MouseWheelEvent.WHEEL_BLOCK_SCROLL</code>
339 * @see #getScrollType
340 */
341 public int getScrollAmount() {
342 return scrollAmount;
343 }
344
345 /**
346 * Returns the number of "clicks" the mouse wheel was rotated, as an integer.
347 * A partial rotation may occur if the mouse supports a high-resolution wheel.
348 * In this case, the method returns zero until a full "click" has been accumulated.
349 *
350 * @return negative values if the mouse wheel was rotated up/away from
351 * the user, and positive values if the mouse wheel was rotated down/
352 * towards the user
353 * @see #getPreciseWheelRotation
354 */
355 public int getWheelRotation() {
356 return wheelRotation;
357 }
358
359 /**
360 * Returns the number of "clicks" the mouse wheel was rotated, as a double.
361 * A partial rotation may occur if the mouse supports a high-resolution wheel.
362 * In this case, the return value will include a fractional "click".
363 *
364 * @return negative values if the mouse wheel was rotated up or away from
365 * the user, and positive values if the mouse wheel was rotated down or
366 * towards the user
367 * @see #getWheelRotation
368 * @since 1.7
369 */
370 public double getPreciseWheelRotation() {
371 return preciseWheelRotation;
372 }
373
374 /**
375 * This is a convenience method to aid in the implementation of
376 * the common-case MouseWheelListener - to scroll a ScrollPane or
377 * JScrollPane by an amount which conforms to the platform settings.
378 * (Note, however, that <code>ScrollPane</code> and
379 * <code>JScrollPane</code> already have this functionality built in.)
380 * <P>
381 * This method returns the number of units to scroll when scroll type is
382 * MouseWheelEvent.WHEEL_UNIT_SCROLL, and should only be called if
383 * <code>getScrollType</code> returns MouseWheelEvent.WHEEL_UNIT_SCROLL.
384 * <P>
385 * Direction of scroll, amount of wheel movement,
386 * and platform settings for wheel scrolling are all accounted for.
387 * This method does not and cannot take into account value of the
388 * Adjustable/Scrollable unit increment, as this will vary among
389 * scrolling components.
390 * <P>
391 * A simplified example of how this method might be used in a
392 * listener:
393 * <pre>
394 * mouseWheelMoved(MouseWheelEvent event) {
395 * ScrollPane sp = getScrollPaneFromSomewhere();
396 * Adjustable adj = sp.getVAdjustable()
397 * if (MouseWheelEvent.getScrollType() == WHEEL_UNIT_SCROLL) {
398 * int totalScrollAmount =
399 * event.getUnitsToScroll() *
400 * adj.getUnitIncrement();
401 * adj.setValue(adj.getValue() + totalScrollAmount);
402 * }
403 * }
404 * </pre>
405 *
406 * @return the number of units to scroll based on the direction and amount
407 * of mouse wheel rotation, and on the wheel scrolling settings of the
408 * native platform
409 * @see #getScrollType
410 * @see #getScrollAmount
411 * @see MouseWheelListener
412 * @see java.awt.Adjustable
413 * @see java.awt.Adjustable#getUnitIncrement
414 * @see javax.swing.Scrollable
415 * @see javax.swing.Scrollable#getScrollableUnitIncrement
416 * @see java.awt.ScrollPane
417 * @see java.awt.ScrollPane#setWheelScrollingEnabled
418 * @see javax.swing.JScrollPane
419 * @see javax.swing.JScrollPane#setWheelScrollingEnabled
420 */
421 public int getUnitsToScroll() {
422 return scrollAmount * wheelRotation;
423 }
424
425 /**
426 * Returns a parameter string identifying this event.
427 * This method is useful for event-logging and for debugging.
428 *
429 * @return a string identifying the event and its attributes
430 */
431 public String paramString() {
432 String scrollTypeStr = null;
433
434 if (getScrollType() == WHEEL_UNIT_SCROLL) {
435 scrollTypeStr = "WHEEL_UNIT_SCROLL";
436 }
437 else if (getScrollType() == WHEEL_BLOCK_SCROLL) {
438 scrollTypeStr = "WHEEL_BLOCK_SCROLL";
439 }
440 else {
441 scrollTypeStr = "unknown scroll type";
442 }
443 return super.paramString()+",scrollType="+scrollTypeStr+
444 ",scrollAmount="+getScrollAmount()+",wheelRotation="+
445 getWheelRotation()+",preciseWheelRotation="+getPreciseWheelRotation();
446 }
447 }