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