我有一个JSpinner,它的所有整数都为 model
. 我希望它的值随着向下的箭头而增加,而值随着向上的箭头而减少,这与默认的用法完全相反。
我已经做了这个工作,使用一个具有前值的变量,并添加了一个新的变量。Change Listener
. 每当一个值发生变化时,我都会将其与之前的值进行比较。如果它要增加,我就减少它,反之亦然。
我想知道是否有其他的方法来实现它。像一个 listener
谁知道按的是哪个箭头。
SpinnerNumberModel model = new SpinnerNumberModel(5, 1, 100, -1); // Note: -ve step
我的回答 是一种方式。这是另一种方式,通过 ChangeListener
既然你提到了
A ChangeListener
每当spinner字段中的值发生变化时就会触发。
其步骤是
安 SSCCE 的意思。
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));
}
}
请注意,监听器在改变值之前被移除,而在改变值之后被再次添加。如果你不删除-更改-添加监听器,你将最终以StackOverFlow错误告终,因为更改值将一次又一次地触发监听器。
另外,请记住 this
符合 spinner.removeChangeListener(this);
指的是 ChangeListener
. 将该监听器转换为lambda表达式。
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);
});
你将无法删除监听器,因为... ... this
将是指 SpinnerExample
实例而不是监听器。长话短说,保持它是一个匿名类而不是lambda。
另一种实现方式是切换这些按钮的handlerslisteners(可能反射要干扰),但这需要更多的努力。另外,也不能保证对其他的外观和感觉有效,因为它们是在 <LookAndFeel>
-ComboBoxUI
.