com.jidesoft.swing.SimpleScrollPane Maven / Gradle / Ivy
/*
* @(#)FlatScrollPane.java 12/13/2006
*
* Copyright 2002 - 2006 JIDE Software Inc. All rights reserved.
*/
package com.jidesoft.swing;
import com.jidesoft.icons.JideIconsFactory;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.UIResource;
import java.awt.*;
import java.awt.event.*;
/**
* SimpleScrollPane
is a special scroll pane. There is no scroll bar. It just uses four scroll buttons to
* do the scrolling.
*/
public class SimpleScrollPane extends JScrollPane implements ChangeListener, MouseWheelListener {
private AbstractButton _scrollUpButton;
private AbstractButton _scrollDownButton;
private AbstractButton _scrollLeftButton;
private AbstractButton _scrollRightButton;
private int _horizontalUnitIncrement = 10;
private boolean _horizontalUnitIncrementSet = false;
private int _verticalUnitIncrement = 10;
private boolean _verticalUnitIncrementSet = false;
private int _repeatDelay = 50;
private boolean _scrollOnRollover = true;
public static final String SCROLL_UP_BUTTON = "SCROLL_UP_BUTTON";
public static final String SCROLL_DOWN_BUTTON = "SCROLL_DOWN_BUTTON";
public static final String SCROLL_LEFT_BUTTON = "SCROLL_LEFT_BUTTON";
public static final String SCROLL_RIGHT_BUTTON = "SCROLL_RIGHT_BUTTON";
/**
* Creates a JideScrollPane
that displays the view component in a viewport whose view position can be
* controlled with a pair of scrollbars. The scrollbar policies specify when the scrollbars are displayed, For
* example, if vsbPolicy
is VERTICAL_SCROLLBAR_AS_NEEDED
then the vertical scrollbar only
* appears if the view doesn't fit vertically. The available policy settings are listed at {@link
* #setVerticalScrollBarPolicy} and {@link #setHorizontalScrollBarPolicy}.
*
* @param view the component to display in the scrollpanes viewport
* @param vsbPolicy an integer that specifies the vertical scrollbar policy
* @param hsbPolicy an integer that specifies the horizontal scrollbar policy
* @see #setViewportView
*/
public SimpleScrollPane(Component view, int vsbPolicy, int hsbPolicy) {
setLayout(new SimpleScrollPaneLayout.UIResource());
setVerticalScrollBarPolicy(vsbPolicy);
setHorizontalScrollBarPolicy(hsbPolicy);
setViewport(createViewport());
setScrollUpButton(createScrollButton(SwingConstants.NORTH));
setScrollDownButton(createScrollButton(SwingConstants.SOUTH));
setScrollLeftButton(createScrollButton(SwingConstants.WEST));
setScrollRightButton(createScrollButton(SwingConstants.EAST));
if (null != view) {
setViewportView(view);
}
updateButtonState();
setOpaque(true);
setFocusable(false);
if (getHorizontalScrollBar() != null) {
getHorizontalScrollBar().setVisible(false);
getHorizontalScrollBar().setFocusable(false);
}
if (getVerticalScrollBar() != null) {
getVerticalScrollBar().setVisible(false);
getVerticalScrollBar().setFocusable(false);
}
updateUI();
if (!getComponentOrientation().isLeftToRight()) {
viewport.setViewPosition(new Point(Integer.MAX_VALUE, 0));
}
if (this.isWheelScrollingEnabled())
this.addMouseWheelListener(this);
}
/**
* Creates a JideScrollPane
that displays the contents of the specified component, where both
* horizontal and vertical scrollbars appear whenever the component's contents are larger than the view.
*
* @param view the component to display in the scrollpane's viewport
* @see #setViewportView
*/
public SimpleScrollPane(Component view) {
this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
/**
* Creates an empty (no viewport view) JideScrollPane
with specified scrollbar policies. The available
* policy settings are listed at {@link #setVerticalScrollBarPolicy} and {@link #setHorizontalScrollBarPolicy}.
*
* @param vsbPolicy an integer that specifies the vertical scrollbar policy
* @param hsbPolicy an integer that specifies the horizontal scrollbar policy
* @see #setViewportView
*/
public SimpleScrollPane(int vsbPolicy, int hsbPolicy) {
this(null, vsbPolicy, hsbPolicy);
}
/**
* Creates an empty (no viewport view) JideScrollPane
where both horizontal and vertical scrollbars
* appear when needed.
*/
public SimpleScrollPane() {
this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
@Override
public void updateUI() {
super.updateUI();
setLayout(new SimpleScrollPaneLayout.UIResource());
LookAndFeel.installBorder(this, "JideScrollPane.border");
getViewport().addChangeListener(this);
}
public void stateChanged(ChangeEvent e) {
if (e.getSource() == getViewport()) {
updateButtonState();
}
}
public AbstractButton getScrollUpButton() {
return _scrollUpButton;
}
public void setScrollUpButton(AbstractButton scrollUpButton) {
AbstractButton old = getScrollUpButton();
_scrollUpButton = scrollUpButton;
add(_scrollUpButton, SCROLL_UP_BUTTON);
firePropertyChange("scrollUpButton", old, _scrollUpButton);
revalidate();
repaint();
}
public AbstractButton getScrollDownButton() {
return _scrollDownButton;
}
public void setScrollDownButton(AbstractButton scrollDownButton) {
AbstractButton old = getScrollDownButton();
_scrollDownButton = scrollDownButton;
add(_scrollDownButton, SCROLL_DOWN_BUTTON);
firePropertyChange("scrollDownButton", old, _scrollDownButton);
revalidate();
repaint();
}
public AbstractButton getScrollLeftButton() {
return _scrollLeftButton;
}
public void setScrollLeftButton(AbstractButton scrollLeftButton) {
AbstractButton old = getScrollLeftButton();
_scrollLeftButton = scrollLeftButton;
add(_scrollLeftButton, SCROLL_LEFT_BUTTON);
firePropertyChange("scrollLeftButton", old, _scrollLeftButton);
revalidate();
repaint();
}
public AbstractButton getScrollRightButton() {
return _scrollRightButton;
}
public void setScrollRightButton(AbstractButton scrollRightButton) {
AbstractButton old = getScrollRightButton();
_scrollRightButton = scrollRightButton;
add(_scrollRightButton, SCROLL_RIGHT_BUTTON);
firePropertyChange("scrollRightButton", old, _scrollRightButton);
revalidate();
repaint();
}
/**
* The scroll button for SimpleScrollPane. You can extend this class to create your own buttons.
*/
public class ScrollButton extends JideButton implements MouseListener, ActionListener, UIResource {
private int _type;
private Timer _timer;
/**
* Creates a ScrollButton.
*
* @param type one of the four values - NORTH, SOUTH, WEST, EAST as defined in SwingConstants.
*/
public ScrollButton(int type) {
_type = type;
switch (type) {
case SwingConstants.NORTH:
setIcon(JideIconsFactory.getImageIcon(JideIconsFactory.Arrow.UP));
break;
case SwingConstants.SOUTH:
setIcon(JideIconsFactory.getImageIcon(JideIconsFactory.Arrow.DOWN));
break;
case SwingConstants.WEST:
setIcon(JideIconsFactory.getImageIcon(JideIconsFactory.Arrow.LEFT));
break;
case SwingConstants.EAST:
setIcon(JideIconsFactory.getImageIcon(JideIconsFactory.Arrow.RIGHT));
break;
}
addActionListener(this);
addMouseListener(this);
setPreferredSize(new Dimension(10, 10));
setMinimumSize(new Dimension(10, 10));
}
public void actionPerformed(ActionEvent e) {
scroll(getViewport(), _type);
updateButtonState();
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
if (!isScrollOnRollover()) {
startTimer(e, 500);
}
else {
updateTimer(e);
}
}
public void mouseReleased(MouseEvent e) {
if (!isScrollOnRollover()) {
stopTimer();
}
else {
updateTimer(e);
}
}
public void mouseEntered(MouseEvent e) {
if (isScrollOnRollover()) {
startTimer(e, 500);
}
}
private void updateTimer(MouseEvent e) {
if (_timer != null) {
_timer.setDelay(getDelay(e));
}
}
private void startTimer(MouseEvent e, int initDelay) {
stopTimer();
_timer = new Timer(getDelay(e), this);
_timer.setInitialDelay(initDelay);
_timer.start();
}
private void stopTimer() {
if (_timer != null) {
_timer.stop();
_timer = null;
}
}
private int getDelay(MouseEvent e) {
if (isScrollOnRollover()) {
return SwingUtilities.isLeftMouseButton(e) ? getRepeatDelay() : getRepeatDelay() * 2;
}
else {
return getRepeatDelay();
}
}
public void mouseExited(MouseEvent e) {
if (isScrollOnRollover()) {
stopTimer();
}
}
}
/**
* Creates the scroll button. You can override this method to change the attributes on the button. For example, you
* can do this to create a bigger scroll button.
*
* SimpleScrollPane pane = new SimpleScrollPane(){
* protected AbstractButton createScrollButton(int type) {
* AbstractButton scrollButton = super.createScrollButton(type);
* scrollButton.setPreferredSize(new Dimension(20, 20));
* return scrollButton;
* }
* };
*
*
* @param type the type of the scroll button. It could be {@link javax.swing.SwingConstants#NORTH}, {@link
* javax.swing.SwingConstants#SOUTH}, {@link javax.swing.SwingConstants#WEST} or {@link
* javax.swing.SwingConstants#EAST} .
* @return the scroll button.
*/
protected AbstractButton createScrollButton(int type) {
return new ScrollButton(type);
}
protected void updateButtonState() {
Point p = viewport.getViewPosition();
_scrollUpButton.setEnabled(p.y != 0);
_scrollDownButton.setEnabled(p.y != viewport.getViewSize().height - viewport.getViewRect().height);
_scrollLeftButton.setEnabled(p.x != 0);
_scrollRightButton.setEnabled(p.x != viewport.getViewSize().width - viewport.getViewRect().width);
revalidate();
repaint();
}
public void scroll(JViewport viewport, int type) {
Point p = viewport.getViewPosition();
JViewport vp = getViewport();
switch (type) {
case SwingConstants.NORTH:
if (!_verticalUnitIncrementSet && (vp != null) &&
(vp.getView() instanceof Scrollable)) {
Scrollable view = (Scrollable) (vp.getView());
Rectangle vr = vp.getViewRect();
p.y -= view.getScrollableUnitIncrement(vr, SwingConstants.VERTICAL, -1);
}
else {
p.y -= getVerticalUnitIncrement();
}
if (p.y < 0) {
p.y = 0;
}
break;
case SwingConstants.SOUTH:
if (!_verticalUnitIncrementSet && (vp != null) &&
(vp.getView() instanceof Scrollable)) {
Scrollable view = (Scrollable) (vp.getView());
Rectangle vr = vp.getViewRect();
p.y += view.getScrollableUnitIncrement(vr, SwingConstants.VERTICAL, 1);
}
else {
p.y += getVerticalUnitIncrement();
}
if (p.y + viewport.getViewRect().height > viewport.getViewSize().height) {
p.y = viewport.getViewSize().height - viewport.getViewRect().height;
}
break;
case SwingConstants.WEST:
if (!_horizontalUnitIncrementSet && (vp != null) &&
(vp.getView() instanceof Scrollable)) {
Scrollable view = (Scrollable) (vp.getView());
Rectangle vr = vp.getViewRect();
p.x -= view.getScrollableUnitIncrement(vr, SwingConstants.HORIZONTAL, -1);
}
else {
p.x -= getHorizontalUnitIncrement();
}
if (p.x < 0) {
p.x = 0;
}
break;
case SwingConstants.EAST:
if (!_horizontalUnitIncrementSet && (vp != null) &&
(vp.getView() instanceof Scrollable)) {
Scrollable view = (Scrollable) (vp.getView());
Rectangle vr = vp.getViewRect();
p.x += view.getScrollableUnitIncrement(vr, SwingConstants.HORIZONTAL, 1);
}
else {
p.x += getHorizontalUnitIncrement();
}
if (p.x + viewport.getViewRect().width > viewport.getViewSize().width) {
p.x = viewport.getViewSize().width - viewport.getViewRect().width;
}
break;
}
viewport.setViewPosition(p);
}
@Override
public Rectangle getViewportBorderBounds() {
Rectangle borderR = new Rectangle(getSize());
Insets insets = getInsets();
borderR.x = insets.left;
borderR.y = insets.top;
borderR.width -= insets.left + insets.right;
borderR.height -= insets.top + insets.bottom;
if (_scrollUpButton != null && _scrollUpButton.isVisible()) {
borderR.y += _scrollUpButton.getHeight();
borderR.height -= _scrollUpButton.getHeight();
}
if (_scrollLeftButton != null && _scrollLeftButton.isVisible()) {
borderR.x += _scrollLeftButton.getWidth();
borderR.width -= _scrollLeftButton.getWidth();
}
if (_scrollDownButton != null && _scrollDownButton.isVisible()) {
borderR.height -= _scrollDownButton.getHeight();
}
if (_scrollRightButton != null && _scrollRightButton.isVisible()) {
borderR.width -= _scrollRightButton.getWidth();
}
return borderR;
}
public int getHorizontalUnitIncrement() {
return _horizontalUnitIncrement;
}
public void setHorizontalUnitIncrement(int horizontalUnitIncrement) {
_horizontalUnitIncrementSet = true;
if (horizontalUnitIncrement != _horizontalUnitIncrement) {
int old = _horizontalUnitIncrement;
_horizontalUnitIncrement = horizontalUnitIncrement;
firePropertyChange("horizontalUnitIncrement", old, _horizontalUnitIncrement);
}
}
public int getVerticalUnitIncrement() {
return _verticalUnitIncrement;
}
public void setVerticalUnitIncrement(int verticalUnitIncrement) {
_verticalUnitIncrementSet = true;
if (verticalUnitIncrement != _verticalUnitIncrement) {
int old = _verticalUnitIncrement;
_verticalUnitIncrement = verticalUnitIncrement;
firePropertyChange("verticalUnitIncrement", old, _verticalUnitIncrement);
}
}
/**
* Checks if the scroll button scrolls on rollover.
*
* @return true if it scrolls on rollover.
*/
public boolean isScrollOnRollover() {
return _scrollOnRollover;
}
/**
* Sets scroll on rollover. If true, the scrolling will start when mouse is placed above the scroll button. If
* false, the scrolling will start only when you click or press and hold the mouse button.
*
* @param scrollOnRollover true or false.
*/
public void setScrollOnRollover(boolean scrollOnRollover) {
if (_scrollOnRollover != scrollOnRollover) {
boolean old = _scrollOnRollover;
_scrollOnRollover = scrollOnRollover;
firePropertyChange("scrollOnRollover", old, _scrollOnRollover);
}
}
/**
* Gets the delay in ms between each unit scrolling.
*
* @return the delay.
*/
public int getRepeatDelay() {
return _repeatDelay;
}
/**
* Sets the delay in ms between each unit scrolling. By default, it's 50. The big thenumberr, the slow the
* scrolling.
*
* @param repeatDelay the new repeat delay.
*/
public void setRepeatDelay(int repeatDelay) {
if (repeatDelay != _repeatDelay) {
int old = _repeatDelay;
_repeatDelay = repeatDelay;
firePropertyChange("repeatDelay", old, _repeatDelay);
}
}
public void mouseWheelMoved(MouseWheelEvent e) {
if (this.isWheelScrollingEnabled() && e.getScrollAmount() != 0) {
boolean scrollingUp = (e.getWheelRotation() >= 0);
int direction = SwingConstants.CENTER;
if (!this.isButtonVisible(scrollingUp))
return;
direction = this.getScrollDirection(scrollingUp);
if (direction != SwingConstants.CENTER)
this.scroll(this.getViewport(), direction);
}
}
private boolean isButtonVisible(boolean scrollingUp) {
if (scrollingUp)
return (((_scrollUpButton != null) && _scrollUpButton.isVisible()) ||
((_scrollLeftButton != null) && _scrollLeftButton.isVisible()));
else
return (((_scrollDownButton != null) && _scrollDownButton.isVisible()) ||
((_scrollRightButton != null) && _scrollRightButton.isVisible()));
}
private int getScrollDirection(boolean scrollingUp) {
if (scrollingUp) {
if ((_scrollUpButton != null) && _scrollUpButton.isVisible()) return SwingConstants.SOUTH;
if ((_scrollLeftButton != null) && _scrollLeftButton.isVisible()) return SwingConstants.EAST;
}
else {
if ((_scrollDownButton != null) && _scrollDownButton.isVisible()) return SwingConstants.NORTH;
if ((_scrollRightButton != null) && _scrollRightButton.isVisible()) return SwingConstants.WEST;
}
return SwingConstants.CENTER;
}
@Override
public void setWheelScrollingEnabled(boolean handleWheel) {
if (handleWheel && !isWheelScrollingEnabled())
this.addMouseWheelListener(this);
if (!handleWheel && isWheelScrollingEnabled())
this.removeMouseWheelListener(this);
super.setWheelScrollingEnabled(handleWheel);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy