/* * Copyright 2001-2008 Geert Bevin (gbevin[remove] at uwyn dot com) * Licensed under the Apache License, Version 2.0 (the "License") * $Id: AutoScroll.java 3918 2008-04-14 17:35:35Z gbevin $ */ package com.uwyn.rife.gui.old; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import javax.swing.*; abstract class AutoScroll extends AbstractAction implements MouseListener, MouseMotionListener { static final int AUTO_SCROLL_DELAY = 40; static final int VISUAL_ASSISTANCE_HORIZONTAL_LEFT = 0; static final int VISUAL_ASSISTANCE_HORIZONTAL_MIDDLE = 1; static final int VISUAL_ASSISTANCE_HORIZONTAL_RIGHT = 2; static final int VISUAL_ASSISTANCE_VERTICAL_TOP = 3; static final int VISUAL_ASSISTANCE_VERTICAL_MIDDLE = 4; static final int VISUAL_ASSISTANCE_VERTICAL_BOTTOM = 5; private StructurePanel mStructurePanel = null; private JScrollPane mScrollPane = null; private Point mFirstDragDestination = null; private JComponent mMouseEventGeneratingComponent = null; private Timer mTimer = null; private Rectangle mViewRect = null; private int mViewTopLeftX = 0; private int mViewTopLeftY = 0; private int mViewBottomRightX = 0; private int mViewBottomRightY = 0; private int mScrollOffsetX = 0; private int mScrollOffsetY = 0; private boolean mContinueToScroll = true; private int mScrollpaneLocationOnGlasspaneX = 0; private int mScrollpaneLocationOnGlasspaneY = 0; private Rectangle mGlasspaneClip = null; AutoScroll(StructurePanel structurePanel) { mStructurePanel = structurePanel; mScrollPane = structurePanel.getScrollPane(); } AutoScroll(StructurePanel structurePanel, Point firstDestination, JComponent mouseEventGeneratingComponent) { mStructurePanel = structurePanel; mScrollPane = structurePanel.getScrollPane(); AutoScroll.this.initializeAutoScroll(firstDestination, mouseEventGeneratingComponent); } final void initializeAutoScroll(Point firstDestination, JComponent mouseEventGeneratingComponent) { mStructurePanel.setScrollActive(true); mStructurePanel.repaint(); mMouseEventGeneratingComponent = mouseEventGeneratingComponent; mMouseEventGeneratingComponent.removeMouseListener((MouseListener)mMouseEventGeneratingComponent); mMouseEventGeneratingComponent.removeMouseMotionListener((MouseMotionListener)mMouseEventGeneratingComponent); mMouseEventGeneratingComponent.addMouseListener(AutoScroll.this); mMouseEventGeneratingComponent.addMouseMotionListener(AutoScroll.this); mFirstDragDestination = convertDestinationPoint(new Point(firstDestination)); prepareVisualAssistance(); SwingUtilities.invokeLater(new StartAutoScroll(firstDestination)); } private class StartAutoScroll extends Thread { private Point mFirstDragDestination = null; public StartAutoScroll(Point firstDestination) { mFirstDragDestination = firstDestination; } public void run() { if(mContinueToScroll) { calculateDifferences(mFirstDragDestination); drawVisualAssistance(); mTimer = new Timer(AUTO_SCROLL_DELAY, AutoScroll.this); mTimer.start(); } } } abstract void prepareVisualAssistanceCustom(); abstract void calculateVisualAssistanceCustom(Point destination, int horizontalId, int verticalId); abstract void eraseVisualAssistanceCustom(Graphics2D g2d); abstract void updateVisualAssistanceAfterScroll(int horizontalOffset, int verticalOffset); abstract void drawVisualAssistanceCustom(Graphics2D g2d); abstract void cleanupVisualAssistanceCustom(); Point convertDestinationPoint(Point destination) { return destination; } final void prepareVisualAssistance() { mViewRect = mScrollPane.getViewport().getViewRect(); mScrollpaneLocationOnGlasspaneX = mScrollPane.getLocationOnScreen().x-((JFrame)mStructurePanel.getTopLevelAncestor()).getContentPane().getLocationOnScreen().x+1; mScrollpaneLocationOnGlasspaneY = mScrollPane.getLocationOnScreen().y-((JFrame)mStructurePanel.getTopLevelAncestor()).getContentPane().getLocationOnScreen().y+1; JMenuBar menubar = ((JFrame)mStructurePanel.getTopLevelAncestor()).getJMenuBar(); if(menubar != null) { mScrollpaneLocationOnGlasspaneY += menubar.getHeight(); } mGlasspaneClip = new Rectangle(mScrollpaneLocationOnGlasspaneX, mScrollpaneLocationOnGlasspaneY, (int)mViewRect.getWidth(), (int)mViewRect.getHeight()); prepareVisualAssistanceCustom(); } final int getScrollpaneLocationOnGlasspaneX() { return mScrollpaneLocationOnGlasspaneX; } final int getScrollpaneLocationOnGlasspaneY() { return mScrollpaneLocationOnGlasspaneY; } final int getViewRectWidth() { return (int)mViewRect.getWidth(); } final int getViewRectHeight() { return (int)mViewRect.getHeight(); } final StructurePanel getStructurePanel() { return mStructurePanel; } final JScrollPane getScrollPane() { return mScrollPane; } final Point getFirstDragDestination() { return mFirstDragDestination; } final JComponent getMouseEventGeneratingComponent() { return mMouseEventGeneratingComponent; } final void calculateDifferences(Point destination) { convertDestinationPoint(destination); calculateOffsets(destination); calculateVisualAssistance(destination); } final void calculateOffsets(Point destination) { mViewTopLeftX = (int)mViewRect.getX(); mViewTopLeftY = (int)mViewRect.getY(); mViewBottomRightX = (int)(mViewRect.getX()+mViewRect.getWidth()-1); mViewBottomRightY = (int)(mViewRect.getY()+mViewRect.getHeight()-1); mScrollOffsetX = 0; if(destination.x < mViewTopLeftX) { mScrollOffsetX = destination.x-mViewTopLeftX; } else if(destination.x > mViewBottomRightX) { mScrollOffsetX = destination.x-mViewBottomRightX; } mScrollOffsetY = 0; if(destination.y < mViewTopLeftY) { mScrollOffsetY = destination.y-mViewTopLeftY; } else if(destination.y > mViewBottomRightY) { mScrollOffsetY = destination.y-mViewBottomRightY; } } final void calculateVisualAssistance(Point destination) { mViewRect = mScrollPane.getViewport().getViewRect(); mViewTopLeftX = (int)mViewRect.getX(); mViewTopLeftY = (int)mViewRect.getY(); mViewBottomRightX = (int)(mViewRect.getX()+mViewRect.getWidth()-1); mViewBottomRightY = (int)(mViewRect.getY()+mViewRect.getHeight()-1); int horizontal_id = -1; if(destination.x < mViewTopLeftX) { horizontal_id = VISUAL_ASSISTANCE_HORIZONTAL_LEFT; } else if(destination.x > mViewBottomRightX) { horizontal_id = VISUAL_ASSISTANCE_HORIZONTAL_RIGHT; } else { horizontal_id = VISUAL_ASSISTANCE_HORIZONTAL_MIDDLE; } int vertical_id = -1; if(destination.y < mViewTopLeftY) { vertical_id = VISUAL_ASSISTANCE_VERTICAL_TOP; } else if(destination.y > mViewBottomRightY) { vertical_id = VISUAL_ASSISTANCE_VERTICAL_BOTTOM; } else { vertical_id = VISUAL_ASSISTANCE_VERTICAL_MIDDLE; } calculateVisualAssistanceCustom(destination, horizontal_id, vertical_id); } final void eraseVisualAssistance() { Graphics2D g2d = (Graphics2D)((JFrame)mStructurePanel.getTopLevelAncestor()).getGlassPane().getGraphics(); g2d.setClip(mGlasspaneClip); eraseVisualAssistanceCustom(g2d); } final void drawVisualAssistance() { Graphics2D g2d = (Graphics2D)((JFrame)mStructurePanel.getTopLevelAncestor()).getGlassPane().getGraphics(); g2d.setClip(mGlasspaneClip); drawVisualAssistanceCustom(g2d); } final public void actionPerformed(ActionEvent e) { if(mContinueToScroll) { reposition(); } } final void reposition() { Point current_position = mScrollPane.getViewport().getViewPosition(); Point new_position = new Point(current_position.x+mScrollOffsetX, current_position.y+mScrollOffsetY); if(new_position.x+mViewRect.width > mStructurePanel.getWidth()) { new_position.x = mStructurePanel.getWidth()-mViewRect.width; } if(new_position.x < 0) { new_position.x = 0; } if(new_position.y+mViewRect.height > mStructurePanel.getHeight()) { new_position.y = mStructurePanel.getHeight()-mViewRect.height; } if(new_position.y < 0) { new_position.y = 0; } eraseVisualAssistance(); mScrollPane.getViewport().setViewPosition(new_position); updateVisualAssistanceAfterScroll(new_position.x-current_position.x, new_position.y-current_position.y); drawVisualAssistance(); } final void finishAutoScroll() { if(mTimer != null) { mContinueToScroll = false; mTimer.stop(); mTimer = null; cleanupVisualAssistanceCustom(); mStructurePanel.resetSelectionRectangle(); mMouseEventGeneratingComponent.removeMouseListener(AutoScroll.this); mMouseEventGeneratingComponent.removeMouseMotionListener(AutoScroll.this); mStructurePanel.setScrollActive(false); mStructurePanel.repaint(); SwingUtilities.invokeLater( new Runnable() { public void run() { mMouseEventGeneratingComponent.addMouseListener((MouseListener)mMouseEventGeneratingComponent); mMouseEventGeneratingComponent.addMouseMotionListener((MouseMotionListener)mMouseEventGeneratingComponent); } } ); } } public void mouseClicked(MouseEvent e) { } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { finishAutoScroll(); ((MouseListener)mMouseEventGeneratingComponent).mouseReleased(e); } public void mouseEntered(MouseEvent e) { finishAutoScroll(); } public void mouseExited(MouseEvent e) { calculateDifferences(e.getPoint()); } public void mouseDragged(MouseEvent e) { calculateDifferences(e.getPoint()); } public void mouseMoved(MouseEvent e) { } }