| /* |
| * Copyright (c) 1997, 2006, Oracle and/or its affiliates. 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. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.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); |
| } |
| |
| } |