jrangeslider.java
来自「用applet实现很多应用小程序」· Java 代码 · 共 845 行 · 第 1/2 页
JAVA
845 行
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);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?