I have a JSpinner that has all integers as model
. I want it's value to increase with the down arrow and value to decrease with up arrow,which is the exact opposite of the default usage.
I have already done this using a variable that has the previous value and added a Change Listener
. Whenever a value changes i compare it to the previous. If it's about to increase i instead decrease it and vice versa.
I wanted to know if there is another way of doing it. Like a listener
who knows which arrow is pressed.
SpinnerNumberModel model = new SpinnerNumberModel(5, 1, 100, -1); // Note: -ve step
Andrew's answer is the way to go. This is another way to achieve it via a ChangeListener
, since you mentioned it.
A ChangeListener
fires every time the value changes in the spinner field.
The steps are:
An SSCCE of what I mean:
public class SpinnerExample extends JFrame {
private int oldValue;
public SpinnerExample() {
super("");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
JSpinner spinner = new JSpinner();
spinner.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int newValue = (int) spinner.getValue();
spinner.removeChangeListener(this);
if (newValue > oldValue) //next value button pressed
spinner.setValue(oldValue - (newValue - oldValue));
else
spinner.setValue(oldValue + (oldValue - newValue));
oldValue = (int) spinner.getValue();
spinner.addChangeListener(this);
}
});
add(spinner);
setLocationByPlatform(true);
pack();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new SpinnerExample().setVisible(true));
}
}
Note that the listener is removed before changing the value and after the change is added again. If you dont remove-change-add the listener, you will end up with a StackOverFlow error since changing the value will fire the listener again and again.
Also, remember that this
in line spinner.removeChangeListener(this);
refers to the ChangeListener
. Converting this listener to a lambda expression:
spinner.addChangeListener(e -> {
int newValue = (int) spinner.getValue();
spinner.removeChangeListener(this);
if (newValue > oldValue) //next value button pressed
spinner.setValue(oldValue - (newValue - oldValue));
else
spinner.setValue(oldValue + (oldValue - newValue));
oldValue = (int) spinner.getValue();
System.out.println("oldValue:" + oldValue);
spinner.addChangeListener(this);
});
you will not able to remove the listener, since the this
will be a reference to SpinnerExample
instance and not the listener. Long story short, keep it an anonymous class and not a lambda.
Another way to accomplish is to switch the handlers/listeners of these buttons (probably reflection will have to interfere), but it will require a lot more effort. Plus there is no guarantee that will work for other look and feels, since they are initiated in <LookAndFeel>
- ComboBoxUI
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.