That's the code of the JSpinner extending class:
//This class is a JSpinner with differential step. the steps
multyplies
//by the factor every fixed number of steps, when the arrow remains
//held down.
//When it's getting closer to the bounds however it slows down,
otherwise
//JSpinner will stop the rolling when it gets within a step from the
bounds.
package diffspinner;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.awt.*;
public class DiffStepSpinner extends JSpinner
{
SpinnerNumberModel model;
int step = 1;
int count = 0;
int previousValue,lastValue=0;
static final int waitFor = 5; //the number of steps before step
increses
static final int accFactor = 2; //the factor the step changes
boolean pressed = false; //holds whether one of the spinner's keys
is currently
// pressed
public void increaseCount()
{
count++;
}
public int getCount()
{
return count;
}
public int getStep()
{
return step;
}
public boolean isPressed()
{
return pressed;
}
void increaseStep()
{
step*=accFactor;
}
public void decreseStep()
{
step/=accFactor;
}
void setSingleStep()
{
step = 1;
}
void zeroCount()
{
count = 0;
}
void setPressed(boolean bool)
{
pressed = bool;
}
class MyChangeListener implements ChangeListener
{
DiffStepSpinner adaptee;
int currentVal,min,max;
public MyChangeListener(DiffStepSpinner adaptee)
{
this.adaptee = adaptee;
}
//This function is called when spinner's values change. it checks
whether
//mouse key is pressed (using boolean data memebr isPressed that
is being
//updated by a mouse listener)
//if increasing the step will cause the value to go out of bounnds
//this function will increase the step.
//otherwise, if the mouse (the arrow key as far as we're
concerned)
//is pressed long enough this function will increase the step
public void stateChanged(ChangeEvent changeEvent)
{
currentVal = ((Integer)adaptee.getValue()).intValue();
if(currentVal == lastValue)
return;
min = ((Integer)((SpinnerNumberModel)adaptee.getModel()).getMinimum()).intValue();
max = ((Integer)((SpinnerNumberModel)adaptee.getModel()).getMaximum()).intValue();
if(adaptee.isPressed())
{
if ( (currentVal > lastValue && currentVal + step > max) ||
currentVal < lastValue && currentVal - step < min)
{
adaptee.decreseStep();
}
else
{
adaptee.increaseCount();
if (adaptee.getCount() == waitFor) {
adaptee.zeroCount();
adaptee.increaseStep();
}
}
model.setStepSize(new Integer(adaptee.getStep()));
}
lastValue = currentVal;
}
}
public DiffStepSpinner(Integer val,Integer min,Integer max)
{
this.setValue(val);
previousValue = val.intValue();
((SpinnerNumberModel)this.getModel()).setMinimum(min);
((SpinnerNumberModel)this.getModel()).setMaximum(max);
this.addChangeListener(new MyChangeListener (this));
this.model = (SpinnerNumberModel)this.getModel();
int compCount = this.getComponentCount();
for (int i=0;i<compCount;i++)
this.getComponent(i).addMouseListener(new
MyMouseListener(this));
}
class MyMouseListener implements MouseListener
{
DiffStepSpinner adaptee;
public MyMouseListener (DiffStepSpinner adaptee)
{
this.adaptee = adaptee;
}
public void mouseClicked(MouseEvent mouseEvent)
{
}
public void mousePressed(MouseEvent mouseEvent)
{
adaptee.setPressed(true);
}
public void mouseReleased(MouseEvent mouseEvent)
{
adaptee.setPressed(false);
adaptee.setSingleStep();
model.setStepSize(new Integer(adaptee.getStep()));
}
public void mouseEntered(MouseEvent mouseEvent){}
public void mouseExited(MouseEvent mouseEvent){}
}
}
and here is a simple examle of how to use it (basically just the same
as
JSpinnr) :
package diffspinner;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Frame1 extends JFrame {
JPanel contentPane;
BorderLayout borderLayout1 = new BorderLayout();
//Construct the frame
public Frame1() {
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try {
jbInit();
}
catch(Exception e) {
e.printStackTrace();
}
}
//Component initialization
private void jbInit() throws Exception {
contentPane = (JPanel) this.getContentPane();
contentPane.setLayout(null);
this.setSize(new Dimension(400, 300));
this.setTitle("Frame Title");
DiffStepSpinner spinner = new DiffStepSpinner(new Integer(30),new
Integer(0),new Integer (1000000));
spinner.setBounds(10,10,100,100);
contentPane.add(spinner);
spinner.setVisible(true);
}
//Overridden so we can exit when window is closed
protected void processWindowEvent(WindowEvent e) {
super.processWindowEvent(e);
if (e.getID() == WindowEvent.WINDOW_CLOSING) {
System.exit(0);
}
}
}