/* * RapidMiner * * Copyright (C) 2001-2011 by Rapid-I and the contributors * * Complete list of developers available at our web site: * * http://rapid-i.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.gui.flow; import java.awt.AWTEvent; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.AWTEventListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import javax.swing.JComponent; import javax.swing.SwingUtilities; import javax.swing.Timer; /** * This manages the panning of the process flow design window. * * @author Simon Fischer */ public class PanningManager implements AWTEventListener { private static final int PAN_DELAY = 50; private static final int PAN_STEP_SIZE = 20; private JComponent target; private Point mouseOnScreenPoint; private Timer timer = new Timer(PAN_DELAY, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { scrollNow(); } }); public PanningManager(JComponent target) { super(); this.target = target; timer.setRepeats(true); timer.start(); Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK); } @Override public void eventDispatched(AWTEvent e) { if (e instanceof MouseEvent) { MouseEvent me = (MouseEvent) e; if (!SwingUtilities.isDescendingFrom(me.getComponent(), target)) { return; } if (me.getID() == MouseEvent.MOUSE_RELEASED) { // stop when mouse released mouseOnScreenPoint = null; if (timer.isRunning()) { timer.stop(); } } else if (me.getID() == MouseEvent.MOUSE_DRAGGED && me.getComponent() == target) { mouseOnScreenPoint = me.getLocationOnScreen(); } else if (me.getID() == MouseEvent.MOUSE_PRESSED && me.getComponent() == target) { mouseOnScreenPoint = me.getLocationOnScreen(); timer.start(); } } } private void scrollNow() { if (mouseOnScreenPoint != null && target.isShowing()) { Point origin = target.getLocationOnScreen(); Point relative = new Point(mouseOnScreenPoint.x - origin.x, mouseOnScreenPoint.y - origin.y); Rectangle visibleRect = target.getVisibleRect(); if (!visibleRect.contains(relative)) { int destX = relative.x; if (relative.getX() < visibleRect.getMinX()) { destX = (int)visibleRect.getMinX() - PAN_STEP_SIZE; } if (relative.getX() > visibleRect.getMaxX()) { destX = (int)visibleRect.getMaxX() + PAN_STEP_SIZE; } int destY = relative.y; if (relative.getY() < visibleRect.getMinY()) { destY = (int)visibleRect.getMinY() - PAN_STEP_SIZE; } if (relative.getY() > visibleRect.getMaxY()) { destY = (int)visibleRect.getMaxY() + PAN_STEP_SIZE; } target.scrollRectToVisible(new Rectangle(new Point(destX, destY))); } } } }