--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/swing/Autoscroller.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,179 @@
+/*
+ * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.swing;
+
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * Autoscroller is responsible for generating synthetic mouse dragged
+ * events. It is the responsibility of the Component (or its MouseListeners)
+ * that receive the events to do the actual scrolling in response to the
+ * mouse dragged events.
+ *
+ * @author Dave Moore
+ * @author Scott Violet
+ */
+class Autoscroller implements ActionListener {
+ /**
+ * Global Autoscroller.
+ */
+ private static Autoscroller sharedInstance = new Autoscroller();
+
+ // As there can only ever be one autoscroller active these fields are
+ // static. The Timer is recreated as necessary to target the appropriate
+ // Autoscroller instance.
+ private static MouseEvent event;
+ private static Timer timer;
+ private static JComponent component;
+
+ //
+ // The public API, all methods are cover methods for an instance method
+ //
+ /**
+ * Stops autoscroll events from happening on the specified component.
+ */
+ public static void stop(JComponent c) {
+ sharedInstance._stop(c);
+ }
+
+ /**
+ * Stops autoscroll events from happening on the specified component.
+ */
+ public static boolean isRunning(JComponent c) {
+ return sharedInstance._isRunning(c);
+ }
+
+ /**
+ * Invoked when a mouse dragged event occurs, will start the autoscroller
+ * if necessary.
+ */
+ public static void processMouseDragged(MouseEvent e) {
+ sharedInstance._processMouseDragged(e);
+ }
+
+
+ Autoscroller() {
+ }
+
+ /**
+ * Starts the timer targeting the passed in component.
+ */
+ private void start(JComponent c, MouseEvent e) {
+ Point screenLocation = c.getLocationOnScreen();
+
+ if (component != c) {
+ _stop(component);
+ }
+ component = c;
+ event = new MouseEvent(component, e.getID(), e.getWhen(),
+ e.getModifiers(), e.getX() + screenLocation.x,
+ e.getY() + screenLocation.y,
+ e.getXOnScreen(),
+ e.getYOnScreen(),
+ e.getClickCount(), e.isPopupTrigger(),
+ MouseEvent.NOBUTTON);
+
+ if (timer == null) {
+ timer = new Timer(100, this);
+ }
+
+ if (!timer.isRunning()) {
+ timer.start();
+ }
+ }
+
+ //
+ // Methods mirror the public static API
+ //
+
+ /**
+ * Stops scrolling for the passed in widget.
+ */
+ private void _stop(JComponent c) {
+ if (component == c) {
+ if (timer != null) {
+ timer.stop();
+ }
+ timer = null;
+ event = null;
+ component = null;
+ }
+ }
+
+ /**
+ * Returns true if autoscrolling is currently running for the specified
+ * widget.
+ */
+ private boolean _isRunning(JComponent c) {
+ return (c == component && timer != null && timer.isRunning());
+ }
+
+ /**
+ * MouseListener method, invokes start/stop as necessary.
+ */
+ private void _processMouseDragged(MouseEvent e) {
+ JComponent component = (JComponent)e.getComponent();
+ boolean stop = true;
+ if (component.isShowing()) {
+ Rectangle visibleRect = component.getVisibleRect();
+ stop = visibleRect.contains(e.getX(), e.getY());
+ }
+ if (stop) {
+ _stop(component);
+ } else {
+ start(component, e);
+ }
+ }
+
+ //
+ // ActionListener
+ //
+ /**
+ * ActionListener method. Invoked when the Timer fires. This will scroll
+ * if necessary.
+ */
+ public void actionPerformed(ActionEvent x) {
+ JComponent component = Autoscroller.component;
+
+ if (component == null || !component.isShowing() || (event == null)) {
+ _stop(component);
+ return;
+ }
+ Point screenLocation = component.getLocationOnScreen();
+ MouseEvent e = new MouseEvent(component, event.getID(),
+ event.getWhen(), event.getModifiers(),
+ event.getX() - screenLocation.x,
+ event.getY() - screenLocation.y,
+ event.getXOnScreen(),
+ event.getYOnScreen(),
+ event.getClickCount(),
+ event.isPopupTrigger(),
+ MouseEvent.NOBUTTON);
+ component.superProcessMouseMotionEvent(e);
+ }
+
+}