/* * @(#)MarqueePane.java 6/9/2009 * * Copyright 2002 - 2009 JIDE Software Inc. All rights reserved. * */ package com.jidesoft.swing; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * <code>MarqueePane</code> is a subclass of <code>JScrollPane</code> with automation of scrolling. In * <code>MarqueePane</code>, you can define the direction you want the component inside the <code>MarqueePane</code> to * scroll to and the scrolling speed. */ public class MarqueePane extends JScrollPane { private int _scrollDelay = 100; private int _stayDelay = 2000; private int _scrollAmount = 2; private int _scrollDirection = SCROLL_DIRECTION_LEFT; private int _stayPosition = -1; private Timer _scrollTimer = null; private int _scrollTimes; private boolean _reachStayPosition = false; public static final int SCROLL_DIRECTION_LEFT = 0; public static final int SCROLL_DIRECTION_RIGHT = 1; public static final int SCROLL_DIRECTION_UP = 2; public static final int SCROLL_DIRECTION_DOWN = 3; public MarqueePane(Component view) { super(view); startAutoScrolling(); } public MarqueePane() { super(); startAutoScrolling(); } @Override public void updateUI() { super.updateUI(); setViewportBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_NEVER); setHorizontalScrollBarPolicy(HORIZONTAL_SCROLLBAR_NEVER); setWheelScrollingEnabled(false); } /** * Get the scroll frequency which indicating how frequent the Marquee will get repaint. * <p/> * The default value is 100ms. * * @return the scroll frequency. */ public int getScrollDelay() { return _scrollDelay; } /** * Set the scroll frequency which indicating how frequent the Marquee will get repaint. * * @param scrollDelay the scroll frequency */ public void setScrollDelay(int scrollDelay) { _scrollDelay = scrollDelay; } /** * Get the scroll amount between two repaints. * <p/> * The default value is 2. * * @return the step size. */ public int getScrollAmount() { return _scrollAmount; } /** * Set the scroll amount between two repaints. * * @param scrollAmount the step size */ public void setScrollAmount(int scrollAmount) { _scrollAmount = scrollAmount; } /** * Get the scroll direction. * <p/> * The value could be <code>SCROLL_LEFT</code>, <code>SCROLL_RIGHT</code>, <code>SCROLL_UP</code>, * <code>SCROLL_DOWN</code> * <p/> * The default value is <code>SCROLL_LEFT</code>. * * @return the scroll direction. */ public int getScrollDirection() { return _scrollDirection; } /** * set the scroll direction. * * @param scrollDirection the scroll direction */ public void setScrollDirection(int scrollDirection) { _scrollDirection = scrollDirection; } /** * Gets delay time when it reaches a stay position. * <p/> * The default value is 500ms. * * @return the delay time when it reaches a stay position.. */ public int getStayDelay() { return _stayDelay; } /** * Sets stay delay time when it reaches a stay position. * * @param stayDelay the delay time when it reaches a stay position. */ public void setStayDelay(int stayDelay) { _stayDelay = stayDelay; } /** * Stop auto scrolling. The view will stay where it is. */ public void stopAutoScrolling() { if (_scrollTimer != null) { if (_scrollTimer.isRunning()) { _scrollTimer.stop(); } _scrollTimer = null; } } /** * Start auto scrolling. */ public void startAutoScrolling() { stopAutoScrolling(); _scrollTimer = new Timer(getScrollDelay(), new ActionListener() { public void actionPerformed(ActionEvent e) { BoundedRangeModel rangeModel; if (getScrollDirection() == SCROLL_DIRECTION_LEFT || getScrollDirection() == SCROLL_DIRECTION_RIGHT) { rangeModel = getHorizontalScrollBar().getModel(); } else { rangeModel = getVerticalScrollBar().getModel(); } int value = rangeModel.getValue(); if (getScrollDirection() == SCROLL_DIRECTION_LEFT || getScrollDirection() == SCROLL_DIRECTION_UP) { if (value + rangeModel.getExtent() == rangeModel.getMaximum()) { rangeModel.setValue(rangeModel.getMinimum()); _scrollTimes = 0; } else if (value + getScrollAmount() + rangeModel.getExtent() > rangeModel.getMaximum()) { rangeModel.setValue(rangeModel.getMaximum() - rangeModel.getExtent()); } else { rangeModel.setValue(value + getScrollAmount()); _scrollTimes ++; } _reachStayPosition = rangeModel.getValue() == rangeModel.getMinimum(); } else { if (value == rangeModel.getMinimum()) { int maximum = rangeModel.getMaximum(); int extent = rangeModel.getExtent(); rangeModel.setValue(rangeModel.getMaximum() - rangeModel.getExtent()); // In the very beginning, range model need to be reset so we need adjust the value with it. if (maximum != rangeModel.getMaximum() || extent != rangeModel.getExtent()) { rangeModel.setValue(rangeModel.getMaximum() - rangeModel.getExtent()); } _scrollTimes = 0; } else if (value - getScrollAmount() < rangeModel.getMinimum()) { rangeModel.setValue(rangeModel.getMinimum()); } else { rangeModel.setValue(value - getScrollAmount()); _scrollTimes ++; } _reachStayPosition = rangeModel.getValue() == rangeModel.getMinimum() || rangeModel.getValue() == rangeModel.getMaximum(); } if (!_reachStayPosition && getStayPosition() >= 0) { if (_scrollTimes % getStayPosition() == 0) { _reachStayPosition = true; } } if (_scrollTimer != null) { _scrollTimer.setDelay(_reachStayPosition ? getStayDelay() : getScrollDelay()); } } }); _scrollTimer.start(); } /** * Get stay position. * <p/> * With this field, you can let the scrolling stop for <code>getStayTime</code> after scrolling <code>getStayPosition</code> times. * <p/> * The default value is -1, which means no stay position in the middle. * * @return the stay position. */ public int getStayPosition() { return _stayPosition; } /** * Set stay position. * * @param stayPosition the stay position */ public void setStayPosition(int stayPosition) { _stayPosition = stayPosition; } }