Java JSpinner 使用向下箭头增加值

Java JSpinner increase value with down arrow

我有一个 JSpinner,它的所有整数都是 model。我希望它的值随着向下箭头增加而值随着向上箭头减少,这与默认用法完全相反。

我已经使用具有先前值并添加了 Change Listener 的变量完成了此操作。每当值发生变化时,我都会将它与之前的值进行比较。如果它即将增加,我反而减少它,反之亦然。

我想知道是否还有其他方法。就像一个 listener 谁知道按下了哪个箭头。

是要走的路。这是通过 ChangeListener 实现它的另一种方法,因为你提到了它。

A ChangeListener 每次微调器字段中的值更改时都会触发。

步骤是:

  1. 保留其当前值的字段引用。
  2. 侦听器中的新值
  3. 如果新值高于旧值,则表示按下了↑箭头
  4. 否则表示按下了↓箭头
  5. 根据变化,设置相反的值

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));
    }
}

请注意,在更改值之前删除侦听器,然后再次添加更改。如果您不删除-更改-添加侦听器,您最终会遇到 Whosebug 错误,因为更改值会一次又一次地触发侦听器。

此外,请记住 spinner.removeChangeListener(this); 行中的 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 实例而不是侦听器。 长话短说,保持匿名 class 而不是 lambda。

另一种方法是切换这些按钮的handlers/listeners(可能反射会干扰),但需要更多的努力。此外,不能保证其他外观和感觉也适用,因为它们是在 <LookAndFeel>-ComboBoxUI.

中启动的
SpinnerNumberModel model = new SpinnerNumberModel(5, 1, 100, -1); // Note: -ve step