Java JSpinner увеличивает значение со стрелкой вниз - PullRequest
2 голосов
/ 07 мая 2020

У меня есть JSpinner, в котором все целые числа как model. Я хочу, чтобы его значение увеличивалось с помощью стрелки вниз, а значение уменьшалось со стрелкой вверх, что является полной противоположностью использования по умолчанию.

Я уже сделал это, используя переменную с предыдущим значением и добавил Change Listener. Всякий раз, когда значение изменяется, я сравниваю его с предыдущим. Если он собирается увеличиться, то вместо этого уменьшите его, и наоборот.

Я хотел знать, есть ли другой способ сделать это. Как listener кто знает, какая стрелка нажата.

Ответы [ 2 ]

3 голосов
/ 07 мая 2020
SpinnerNumberModel model = new SpinnerNumberModel(5, 1, 100, -1); // Note: -ve step
2 голосов
/ 07 мая 2020

Ответ Эндрю - это путь к go. Это еще один способ добиться этого с помощью ChangeListener, поскольку вы упомянули об этом.

A ChangeListener срабатывает каждый раз, когда значение изменяется в поле счетчика.

Шаги следующие:

  1. Сохранить ссылку на поле с его текущим значением.
  2. Определить новое значение в слушателе
  3. Если новое значение выше старого значения, значит нажата стрелка ↑
  4. В противном случае значит нажата стрелка ↓
  5. По изменению выставить противоположное значение

1023 * 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. Преобразуя этого слушателя в лямбда-выражение:

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, а не на слушателя. Короче говоря, оставьте его анонимным классом, а не лямбдой.

Другой способ выполнить sh - переключить обработчики / слушатели этих кнопок (вероятно, отражение должно мешать ), но для этого потребуется гораздо больше усилий. Кроме того, нет никакой гарантии, что они будут работать для другого внешнего вида, поскольку они инициируются в <LookAndFeel> - ComboBoxUI.

...