package prefuse.util.ui;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.BoundedRangeModel;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.JComponent;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
* <p>Implements a Swing-based Range slider, which allows the user to enter a
* range (minimum and maximum) value.</p>
*
* @author Ben Bederson
* @author Jesse Grosjean
* @author Jon Meyer
* @author Lance Good
* @author jeffrey heer
* @author Colin Combe
*/
public class JRangeSlider extends JComponent
implements MouseListener, MouseMotionListener, KeyListener
{
/*
* NOTE: This is a modified version of the original class distributed by
* Ben Bederson, Jesse Grosjean, and Jon Meyer as part of an HCIL Tech
* Report. It is modified to allow both vertical and horitonal modes.
* It also fixes a bug with offset on the buttons. Also fixed a bug with
* rendering using (x,y) instead of (0,0) as origin. Also modified to
* render arrows as a series of lines rather than as a GeneralPath.
* Also modified to fix rounding errors on toLocal and toScreen.
*
* With inclusion in prefuse, this class has been further modified to use a
* bounded range model, support keyboard commands and more extensize
* parameterization of rendering/appearance options. Furthermore, a stub
* method has been introduced to allow subclasses to perform custom
* rendering within the slider through.
*/
final public static int VERTICAL = 0;
final public static int HORIZONTAL = 1;
final public static int LEFTRIGHT_TOPBOTTOM = 0;
final public static int RIGHTLEFT_BOTTOMTOP = 1;
final public static int PREFERRED_BREADTH = 16;
final public static int PREFERRED_LENGTH = 300;
final protected static int ARROW_SZ = 16;
final protected static int ARROW_WIDTH = 8;
final protected static int ARROW_HEIGHT = 4;
protected BoundedRangeModel model;
protected int orientation;
protected int direction;
protected boolean empty;
protected int increment = 1;
protected int minExtent = 0; // min extent, in pixels
protected ArrayList listeners = new ArrayList();
protected ChangeEvent changeEvent = null;
protected ChangeListener lstnr;
protected Color thumbColor = new Color(150,180,220);
// ------------------------------------------------------------------------
/**
* Create a new range slider.
*
* @param minimum - the minimum value of the range.
* @param maximum - the maximum value of the range.
* @param lowValue - the current low value shown by the range slider's bar.
* @param highValue - the current high value shown by the range slider's bar.
* @param orientation - construct a horizontal or vertical slider?
*/
public JRangeSlider(int minimum, int maximum, int lowValue, int highValue, int orientation) {
this(new DefaultBoundedRangeModel(lowValue, highValue - lowValue, minimum, maximum),
orientation,LEFTRIGHT_TOPBOTTOM);
}
/**
* Create a new range slider.
*
* @param minimum - the minimum value of the range.
* @param maximum - the maximum value of the range.
* @param lowValue - the current low value shown by the range slider's bar.
* @param highValue - the current high value shown by the range slider's bar.
* @param orientation - construct a horizontal or vertical slider?
* @param direction - Is the slider left-to-right/top-to-bottom or right-to-left/bottom-to-top
*/
public JRangeSlider(int minimum, int maximum, int lowValue, int highValue, int orientation, int direction) {
this(new DefaultBoundedRangeModel(lowValue, highValue - lowValue, minimum, maximum),
orientation, direction);
}
/**
* Create a new range slider.
*
* @param model - a BoundedRangeModel specifying the slider's range
* @param orientation - construct a horizontal or vertical slider?
* @param direction - Is the slider left-to-right/top-to-bottom or right-to-left/bottom-to-top
*/
public JRangeSlider(BoundedRangeModel model, int orientation, int direction) {
super.setFocusable(true);
this.model = model;
this.orientation = orientation;
this.direction = direction;
setForeground(Color.LIGHT_GRAY);
this.lstnr = createListener();
model.addChangeListener(lstnr);
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
}
/**
* Create a listener to relay change events from the bounded range model.
* @return a ChangeListener to relay events from the range model
*/
protected ChangeListener createListener() {
return new RangeSliderChangeListener();
}
/**
* Listener that fires a change event when it receives change event from
* the slider list model.
*/
protected class RangeSliderChangeListener implements ChangeListener {
public void stateChanged(ChangeEvent e) {
fireChangeEvent();
}
}
/**
* Returns the current "low" value shown by the range slider's bar. The low
* value meets the constraint minimum <= lowValue <= highValue <= maximum.
*/
public int getLowValue() {
return model.getValue();
}
/**
* Sets the low value shown by this range slider. This causes the range slider to be
* repainted and a ChangeEvent to be fired.
* @param lowValue the low value to use
*/
public void setLowValue(int lowValue) {
int e = (model.getValue()-lowValue)+model.getExtent();
model.setRangeProperties(lowValue, e,
model.getMinimum(), model.getMaximum(), false);
model.setValue(lowValue);
}
/**
* Returns the current "high" value shown by the range slider's bar. The high
* value meets the constraint minimum <= lowValue <= highValue <= maximum.
*/
public int getHighValue() {
return model.getValue()+model.getExtent();
}
/**
* Sets the high value shown by this range slider. This causes the range slider to be
* repainted and a ChangeEvent to be fired.
* @param highValue the high value to use
*/
public void setHighValue(int highValue) {
model.setExtent(highValue-model.getValue());
}
/**
* Set the slider range span.
* @param lowValue the low value of the slider range
* @param highValue the high value of the slider range
*/
public void setRange(int lowValue, int highValue) {
model.setRangeProperties(lowValue, highValue-lowValue,
model.getMinimum(), model.getMaximum(), false);
}
/**
* Gets the minimum possible value for either the low value or the high value.
* @return the minimum possible range value
*/
public int getMinimum() {
return model.getMinimum();
}
/**
* Sets the minimum possible value for either the low value or the high value.
* @param minimum the minimum possible range value
*/
public void setMinimum(int minimum) {
model.setMinimum(minimum);
}
/**
* Gets the maximum possible value for either the low value or the high value.
* @return the maximum possible range value
*/
public int getMaximum() {
return model.getMaximum();
}
/**
* Sets the maximum possible value for either the low value or the high value.
* @param maximum the maximum possible range value
*/
public void setMaximum(int maximum) {
model.setMaximum(maximum);
}
/**
* Sets the minimum extent (difference between low and high values).
* This method <strong>does not</strong> change the current state of the
* model, but can affect all subsequent interaction.
* @param minExtent the minimum extent allowed in subsequent interaction
*/
public void setMinExtent(int minExtent) {
this.minExtent = minExtent;
}
/**
* Sets whether this slider is empty.
* @param empty true if set to empty, false otherwise
*/
public void setEmpty(boolean empty) {
this.empty = empty;
repaint();
}
/**
* Get the slider thumb color. This is the part of the slider between
* the range resize buttons.
* @return the slider thumb color
*/
public Color getThumbColor() {
return thumbColor;
}
/**
* Set the slider thumb color. This is the part of the slider between
* the range resize buttons.
* @param thumbColor the slider thumb color
*/
public void setThumbColor(Color thumbColor) {
this.thumbColor = thumbColor;
}
/**
* Get the BoundedRangeModel backing this slider.
* @return the slider's range model
*/
public BoundedRangeModel getModel() {
return model;
}
/**
* Set the BoundedRangeModel backing this slider.
* @param brm the slider range model to use
*/
public void setModel(BoundedRangeModel brm) {
model.removeChangeListener(lstnr);
model = brm;
model.addChangeListener(lstnr);
repaint();
}
/**
* Registers a listener for ChangeEvents.
* @param cl the ChangeListener to add
*/
public void addChangeListener(ChangeListener cl) {
if ( !listeners.contains(cl) )
listeners.add(cl);
}
/**
* Removes a listener for ChangeEvents.
* @param cl the ChangeListener to remove
*/
public void removeChangeListener(ChangeListener cl) {
listeners.remove(cl);
}
/**
* Fire a change event to all listeners.
*/
protected void fireChangeEvent() {
repaint();
if ( changeEvent == null )
changeEvent = new ChangeEvent(this);
Iterator iter = listeners.iterator();
while ( iter.hasNext() )
((ChangeListener)iter.next()).stateChanged(changeEvent);
}
/**
* @see java.awt.Component#getPreferredSize()
*/
public Dimension getPreferredSize() {
if (orientation == VERTICAL) {
return new Dimension(PREFERRED_BREADTH, PREFERRED_LENGTH);
}
else {
return new Dimension(PREFERRED_LENGTH, PREFERRED_BREADTH);
}
}
// ------------------------------------------------------------------------
// Rendering
/**
* Override this method to perform custom painting of the slider trough.
* @param g a Graphics2D context for rendering
* @param width the width of the slider trough
* @param height the height of the slider trough
*/
protected void customPaint(Graphics2D g, int width, int height) {
// does nothing in this class
// subclasses can override to perform custom painting
}
/**
* @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
*/
public void paintComponent(Graphics g) {
Rectangle bounds = getBounds();
int width = (int)bounds.getWidth() - 1;
int height = (int)bounds.getHeight() - 1;
int min = toScreen(getLowValue());
int max = toScreen(getHighValue());
// Paint the full slider if the slider is marked as empty
if (empty) {
if (direction == LEFTRIGHT_TOPBOTTOM) {
min = ARROW_SZ;
max = (orientation == VERTICAL) ? height-ARROW_SZ : width-ARROW_SZ;
}
else {
min = (orientation == VERTICAL) ? height-ARROW_SZ : width-ARROW_SZ;
max = ARROW_SZ;
}
}
Graphics2D g2 = (Graphics2D)g;
g2.setColor(getBackground());
g2.fillRect(0, 0, width, height);
g2.setColor(getForeground());
g2.drawRect(0, 0, width, height);
customPaint(g2, width, height);
// Draw arrow and thumb backgrounds
g2.setStroke(new BasicStroke(1));
if (orientation == VERTICAL) {
if (direction == LEFTRIGHT_TOPBOTTOM) {
g2.setColor(getForeground());
g2.fillRect(0, min - ARROW_SZ, width, ARROW_SZ-1);
paint3DRectLighting(g2,0,min-ARROW_SZ,width,ARROW_SZ-1);
if ( thumbColor != null ) {
g2.setColor(thumbColor);
g2.fillRect(0, min, width, max - min-1);
paint3DRectLighting(g2,0,min,width,max-min-1);
}
g2.setColor(getForeground());
g2.fillRect(0, max, width, ARROW_SZ-1);
paint3DRectLighting(g2,0,max,width,ARROW_SZ-1);
// Draw arrows
g2.setColor(Color.black);
paintArrow(g2, (width-ARROW_WIDTH) / 2.0, min - ARROW_SZ + (ARROW_SZ-ARROW_HEIGHT) / 2.0, ARROW_WIDTH, ARROW_HEIGHT, true);
paintArrow(g2, (width-ARROW_WIDTH) / 2.0, max + (ARROW_SZ-ARROW_HEIGHT) / 2.0, ARROW_WIDTH, ARROW_HEIGHT, false);
}
else {
g2.setColor(getForeground());
g2.fillRect(0, min, width, ARROW_SZ-1);
paint3DRectLighting(g2,0,min,width,ARROW_SZ-1);
if ( thumbColor != null ) {
g2.setColor(thumbColor);
g2.fillRect(0, max, width, min-max-1);
paint3DRectLighting(g2,0,max,width,min-max-1);
}
g2.setColor(getForeground());
g2.fillRect(0, max-ARROW_SZ, width, ARROW_SZ-1);
paint3DRectLighting(g2,0,max-ARROW_SZ,width,ARROW_SZ-1);
// Draw arrows
g2.setColor(Color.black);
paintArrow(g2, (width-ARROW_WIDTH) / 2.0, min + (ARROW_SZ-ARROW_HEIGHT) / 2.0, ARROW_WIDTH, ARROW_HEIGHT, false);
paintArrow(g2, (width-ARROW_WIDTH) / 2.0, max - ARROW_SZ + (ARROW_SZ-ARROW_HEIGHT) / 2.0, ARROW_WIDTH, ARROW_HEIGHT, true);
}
}
else {
if (direction == LEFTRIGHT_TOPBOTTOM) {
g2.setColor(getForeground());
g2.fillRect(min - ARROW_SZ, 0, ARROW_SZ-1, height);
paint3DRectLighting(g2,min-ARROW_SZ,0,ARROW_SZ-1,height);
if ( thumbColor != null ) {
g2.setColor(thumbColor);
g2.fillRect(min, 0, max - min - 1, height);
paint3DRectLighting(g2,min,0,max-min-1,height);
}
g2.setColor(getForeground());
g2.fillRect(max, 0, ARROW_SZ-1, height);
paint3DRectLighting(g2,max,0,ARROW_SZ-1,height);
// Draw arrows
g2.setColor(Color.black);
paintArrow(g2, min - ARROW_SZ + (ARROW_SZ-ARROW_HEIGHT) / 2.0, (height-ARROW_WIDTH) / 2.0, ARROW_HEIGHT, ARROW_WIDTH, true);
paintArrow(g2, max + (ARROW_SZ-ARROW_HEIGHT) / 2.0, (height-ARROW_WIDTH) / 2.0, ARROW_HEIGHT, ARROW_WIDTH, false);
}
else {
g2.setColor(getForeground());
g2.fillRect(min, 0, ARROW_SZ - 1, height);
paint3DRectLighting(g2,min,0,ARROW_SZ-1,height);
if ( thumbColor != null ) {
g2.setColor(thumbColor);
g2.fillRect(max, 0, min - max - 1, height);
paint3DRectLighting(g2,max,0,min-max-1,height);
}
g2.setColor(getForeground());
g2.fillRect(max-ARROW_SZ, 0, ARROW_SZ-1, height);
paint3DRectLighting(g2,max-ARROW_SZ,0,ARROW_SZ-1,height);
// Draw arrows
g2.setColor(Color.black);
paintArrow(g2, min + (ARROW_SZ-ARROW_HEIGHT) / 2.0, (height-ARROW_WIDTH) / 2.0, ARROW_HEIGHT, ARROW_WIDTH, true);
paintArrow(g2, max - ARROW_SZ + (ARROW_SZ-ARROW_HEIGHT) / 2.0, (height-ARROW_WIDTH) / 2.0, ARROW_HEIGHT, ARROW_WIDTH, false);
}
}
}
/**
* This draws an arrow as a series of lines within the specified box.
* The last boolean specifies whether the point should be at the
* right/bottom or left/top.
*/
protected void paintArrow(Graphics2D g2, double x, double y, int w, int h,
boolean topDown)
{
int intX = (int)(x+0.5);
int intY = (int)(y+0.5);
if (orientation == VERTICAL) {
if (w % 2 == 0) {
w = w - 1;
}
if (topDown) {
for(int i=0; i<(w/2+1); i++) {
g2.drawLine(intX+i,intY+i,intX+w-i-1,intY+i);
}
}
else {
for(int i=0; i<(w/2+1); i++) {
g2.drawLine(intX+w/2-i,intY+i,intX+w-w/2+i-1,intY+i);
}
}
}
else {
if (h % 2 == 0) {
h = h - 1;
}
if (topDown) {
for(int i=0; i<(h/2+1); i++) {
g2.drawLine(intX+i,intY+i,intX+i,intY+h-i-1);
}
}
else {
for(int i=0; i<(h/2+1); i++) {
g2.drawLine(intX+i,intY+h/2-i,intX+i,intY+h-h/2+i-1);
}
}
}
}
/**
* Adds Windows2K type 3D lighting effects
*/
protected void paint3DRectLighting(Graphics2D g2, int x, int y,
int width, int height)
{
g2.setColor(Color.white);
g2.drawLine(x+1,y+1,x+1,y+height-1);
g2.drawLine(x+1,y+1,x+width-1,y+1);
g2.setColor(Color.gray);
g2.drawLine(x+1,y+height-1,x+width-1,y+height-1);
g2.drawLine(x+width-1,y+1,x+width-1,y+height-1);
g2.setColor(Color.darkGray);
g2.drawLine(x,y+height,x+width,y+height);
g2.drawLine(x+width,y,x+width,y+height);
}
/**
* Converts from screen coordinates to a range value.
*/
protected int toLocal(int xOrY) {
Dimension sz = getSize();
int min = getMinimum();
double scale;
if (orientation == VERTICAL) {
scale = (sz.height - (2 * ARROW_SZ)) / (double) (getMaximum() - min);
}
else {
scale = (sz.width - (2 * ARROW_SZ)) / (double) (getMaximum() - min);
}
if (direction == LEFTRIGHT_TOPBOTTOM) {
return (int) (((xOrY - ARROW_SZ) / scale) + min + 0.5);
}
else {
if (orientation == VERTICAL) {
return (int) ((sz.height - xOrY - ARROW_SZ) / scale + min + 0.5);
}
else {
return (int) ((sz.width - xOrY - ARROW_SZ) / scale + min + 0.5);
}
}
}
/**
* Converts from a range value to screen coordinates.
*/
protected int toScreen(int xOrY) {
Dimension sz = getSize();
int min = getMinimum();
double scale;
if (orientation == VERTICAL) {
scale = (sz.height - (2 * ARROW_SZ)) / (double) (getMaximum() - min);
}
else {
scale = (sz.width - (2 * ARROW_SZ)) / (double) (getMaximum() - min);
}
// If the direction is left/right_top/bottom then we subtract the min and multiply times scale
// Otherwise, we have to invert the number by subtracting the value from the height
if (direction == LEFTRIGHT_TOPBOTTOM) {
return (int)(ARROW_SZ + ((xOrY - min) * scale) + 0.5);
}
else {
if (orientation == VERTICAL) {
return (int)(sz.height-(xOrY - min) * scale - ARROW_SZ + 0.5);
}
else {
return (int)(sz.width-(xOrY - min) * scale - ARROW_SZ + 0.5);
}
}
}
/**
* Converts from a range value to screen coordinates.
*/
protected double toScreenDouble(int xOrY) {
Dimension sz = getSize();
int min = getMinimum();
double scale;
if (orientation == VERTICAL) {
scale = (sz.height - (2 * ARROW_SZ)) / (double) (getMaximum()+1 - min);
}
else {
scale = (sz.width - (2 * ARROW_SZ)) / (double) (getMaximum()+1 - min);
}
// If the direction is left/right_top/bottom then we subtract the min and multiply times scale
// Otherwise, we have to invert the number by subtracting the value from the height
if (direction == LEFTRIGHT_TOPBOTTOM) {
return ARROW_SZ + ((xOrY - min) * scale);
}
else {
if (orientation == VERTICAL) {
return sz.height-(xOrY - min) * scale - ARROW_SZ;
}
else {
return sz.width-(xOrY - min) * scale - ARROW_SZ;
}
}
}
// ------------------------------------------------------------------------
// Event Handling
static final int PICK_NONE = 0;
static final int PICK_LEFT_OR_TOP = 1;
static final int PICK_THUMB = 2;
static final int PICK_RIGHT_OR_BOTTOM = 3;
int pick;
int pickOffsetLow;
int pickOffsetHigh;
int mouse;
private int pickHandle(int xOrY) {
int min = toScreen(getLowValue());
int max = toScreen(getHighValue());
int pick = PICK_NONE;
if (direction == LEFTRIGHT_TOPBOTTOM) {
if ((xOrY > (min - ARROW_SZ)) && (xOrY < min)) {
pick = PICK_LEFT_OR_TOP;
} else if ((xOrY >= min) && (xOrY <= max)) {
pick = PICK_THUMB;
} else if ((xOrY > max) && (xOrY < (max + ARROW_SZ))) {
pick = PICK_RIGHT_OR_BOTTOM;
}
}
else {
if ((xOrY > min) && (xOrY < (min + ARROW_SZ))) {
pick = PICK_LEFT_OR_TOP;
} else if ((xOrY <= min) && (xOrY >= max)) {
pick = PICK_THUMB;
} else if ((xOrY > (max - ARROW_SZ) && (xOrY < max))) {
pick = PICK_RIGHT_OR_BOTTOM;
}
}
return pick;
}
private void offset(int dxOrDy) {
model.setValue(model.getValue()+dxOrDy);
}
/**
* @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
*/
public void mousePressed(MouseEvent e) {
if (orientation == VERTICAL) {
pick = pickHandle(e.getY());
pickOffsetLow = e.getY() - toScreen(getLowValue());
pickOffsetHigh = e.getY() - toScreen(getHighValue());
mouse = e.getY();
}
else {
pick = pickHandle(e.getX());
pickOffsetLow = e.getX() - toScreen(getLowValue());
pickOffsetHigh = e.getX() - toScreen(getHighValue());
mouse = e.getX();
}
repaint();
}
/**
* @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
*/
public void mouseDragged(MouseEvent e) {
requestFocus();
int value = (orientation == VERTICAL) ? e.getY() : e.getX();
int minimum = getMinimum();
int maximum = getMaximum();
int lowValue = getLowValue();
int highValue = getHighValue();
switch (pick) {
case PICK_LEFT_OR_TOP:
int low = toLocal(value-pickOffsetLow);
if (low < minimum) {
low = minimum;
}
if (low > maximum - minExtent) {
low = maximum - minExtent;
}
if (low > highValue-minExtent) {
setRange(low, low + minExtent);
}
else
setLowValue(low);
break;
case PICK_RIGHT_OR_BOTTOM:
int high = toLocal(value-pickOffsetHigh);
if (high < minimum + minExtent) {
high = minimum + minExtent;
}
if (high > maximum) {
high = maximum;
}
if (high < lowValue+minExtent) {
setRange(high - minExtent, high);
}
else
setHighValue(high);
break;
case PICK_THUMB:
int dxOrDy = toLocal(value - pickOffsetLow) - lowValue;
if ((dxOrDy < 0) && ((lowValue + dxOrDy) < minimum)) {
dxOrDy = minimum - lowValue;
}
if ((dxOrDy > 0) && ((highValue + dxOrDy) > maximum)) {
dxOrDy = maximum - highValue;
}
if (dxOrDy != 0) {
offset(dxOrDy);
}
break;
}
}
/**
* @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
*/
public void mouseReleased(MouseEvent e) {
pick = PICK_NONE;
repaint();
}
/**
* @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
*/
public void mouseMoved(MouseEvent e) {
if (orientation == VERTICAL) {
switch (pickHandle(e.getY())) {
case PICK_LEFT_OR_TOP:
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
break;
case PICK_RIGHT_OR_BOTTOM:
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
break;
case PICK_THUMB:
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
break;
case PICK_NONE :
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
break;
}
}
else {
switch (pickHandle(e.getX())) {
case PICK_LEFT_OR_TOP:
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
break;
case PICK_RIGHT_OR_BOTTOM:
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
break;
case PICK_THUMB:
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
break;
case PICK_NONE :
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
break;
}
}
}
/**
* @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
*/
public void mouseClicked(MouseEvent e) {
}
/**
* @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
*/
public void mouseEntered(MouseEvent e) {
}
/**
* @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
*/
public void mouseExited(MouseEvent e) {
}
private void grow(int increment) {
model.setRangeProperties(model.getValue()-increment,
model.getExtent()+2*increment,
model.getMinimum(), model.getMaximum(), false);
}
/**
* @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
*/
public void keyPressed(KeyEvent e) {
int kc = e.getKeyCode();
boolean v = (orientation == VERTICAL);
boolean d = (kc == KeyEvent.VK_DOWN);
boolean u = (kc == KeyEvent.VK_UP);
boolean l = (kc == KeyEvent.VK_LEFT);
boolean r = (kc == KeyEvent.VK_RIGHT);
int minimum = getMinimum();
int maximum = getMaximum();
int lowValue = getLowValue();
int highValue = getHighValue();
if ( v&&r || !v&&u ) {
if ( lowValue-increment >= minimum &&
highValue+increment <= maximum ) {
grow(increment);
}
} else if ( v&&l || !v&&d ) {
if ( highValue-lowValue >= 2*increment ) {
grow(-1*increment);
}
} else if ( v&&d || !v&&l ) {
if ( lowValue-increment >= minimum ) {
offset(-increment);
}
} else if ( v&&u || !v&&r ) {
if ( highValue+increment <= maximum ) {
offset(increment);
}
}
}
/**
* @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
*/
public void keyReleased(KeyEvent e) {
}
/**
* @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
*/
public void keyTyped(KeyEvent e) {
}
} // end of class JRangeSlider