package org.exist.client.xacml;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JViewport;
import javax.swing.Scrollable;
import javax.swing.SwingConstants;
import javax.swing.Timer;
public class AutoScroller implements ActionListener
{
private static final int DELTA = 8;
private static final int DEFAULT_INCREMENT = 42;
private static final int DEFAULT_INITIAL_DELAY = 400;
private static final int DEFAULT_REPEAT_DELAY = 50;
private Component comp;
private Point cursorLocation;
private Timer scrollTimer;
public AutoScroller()
{
scrollTimer = new Timer(DEFAULT_REPEAT_DELAY, this);
scrollTimer.setCoalesce(true);
scrollTimer.setRepeats(true);
scrollTimer.setInitialDelay(DEFAULT_INITIAL_DELAY);
scrollTimer.setDelay(DEFAULT_REPEAT_DELAY);
}
public void stop()
{
comp = null;
cursorLocation = null;
scrollTimer.stop();
}
public void autoscroll(Component comp, Point cursorLocation)
{
this.comp = comp;
this.cursorLocation = cursorLocation;
scrollTimer.restart();
}
public void actionPerformed(ActionEvent event)
{
final Container parent = comp.getParent();
if(!(parent instanceof JViewport))
{return;}
final JViewport view = (JViewport)parent;
final Rectangle rect = view.getViewRect();
int horizontal = 0;
int vertical = 0;
final int verticalDiffTop = cursorLocation.y - rect.y;
final int verticalDiffBottom = rect.height - verticalDiffTop;
final int horizontalDiffLeft = cursorLocation.x - rect.x;
final int horizontalDiffRight = rect.width - horizontalDiffLeft;
if(verticalDiffTop < DELTA)
{vertical = -1;}
else if(verticalDiffBottom < DELTA)
{vertical = 1;}
if(horizontalDiffLeft < DELTA)
{horizontal = -1;}
else if(horizontalDiffRight < DELTA)
{horizontal = 1;}
if(comp instanceof Scrollable)
{
final Scrollable scrollable = (Scrollable)comp;
vertical *= scrollable.getScrollableUnitIncrement(rect, SwingConstants.VERTICAL, vertical);
horizontal *= scrollable.getScrollableUnitIncrement(rect, SwingConstants.HORIZONTAL, horizontal);
}
else
{
vertical *= DEFAULT_INCREMENT;
horizontal *= DEFAULT_INCREMENT;
}
final Dimension viewSize = view.getViewSize();
final Point newPosition = new Point(rect.x + horizontal, rect.y + vertical);
if(newPosition.x < 0)
{newPosition.x = 0;}
else if(newPosition.x > viewSize.width - rect.width)
{newPosition.x = viewSize.width - rect.width;}
if(newPosition.y < 0)
{newPosition.y = 0;}
else if(newPosition.y > viewSize.height - rect.height)
{newPosition.y = viewSize.height - rect.height;}
if(newPosition.x != rect.x || newPosition.y != rect.y)
{
cursorLocation.x += (newPosition.x - rect.x);
cursorLocation.y += (newPosition.y - rect.y);
view.setViewPosition(newPosition);
}
}
}