Java KeyListener не срабатывает на JSpinner

пробовал несколько разных подходов к этому, но пока безуспешно. Просто подумал, не пропустил ли я что-нибудь. У меня есть JSpinner, который является компонентом виджета DateSelector вместе с календарем. Я пытаюсь запустить метод проверки, если пользователь меняет какой-либо текст в JSpinner вместо использования элемента управления «Календарь» или стрелок вверх и вниз JSpinner.

Вот различные подходы, которые я пробовал:

jSpinner1.addKeyListener(kl);

jSpinner1.getEditor().addKeyListener(kl);

((JSpinner.DefaultEditor) jSpinner1.getEditor().getTextField().addKeyListener(kl);

У кого-нибудь есть идеи относительно того, что я делаю неправильно? Спасибо

ОБНОВЛЕНИЕ Извиняюсь, я должен был сказать, что уже добавил ChangeListener в JSpinnerDateModel, который прикреплен к JSpinner. Вот так:

ChangeListener changeListener = new ChangeListener() {
        @Override
        public void stateChanged(ChangeEvent e) {
            dateChanged();
        }
    };

    jSpinnerDateModel.addChangeListener(changeListener);

    KeyListener keyListener = new KeyListener() {

        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void keyPressed(KeyEvent e) {
            System.out.println(e.getKeyChar());
            dateChanged();
        }

        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub

        }

    };
    ((JSpinner.DefaultEditor) jSpinner1.getEditor()).getTextField().addKeyListener(
            keyListener);

Спасибо

откровенный


person Frank    schedule 06.10.2010    source источник


Ответы (3)


JSpinners сами обрабатывают KeyEvents, но запускают ChangeEvents во внешний мир. Добавление ChangeListener должно позволить вам выполнить желаемую проверку.

См. также: Обнаружение изменений значения счетчика (учебники по Java)

person Michael Myers    schedule 06.10.2010
comment
Извиняюсь за то, что не включил эту информацию в исходный вопрос (сейчас я обновил ее), но у меня уже есть ChangeListener, прикрепленный к модели JSpinner. Это улавливает любые изменения, внесенные в значение в JSpinner, но только если пользователь использует элементы управления JSpinner. Я пытаюсь запустить событие нажатия клавиши KeyListener, когда пользователь вручную редактирует значение JSpinner с помощью клавиатуры. Спасибо - person Frank; 06.10.2010
comment
@Frank: ChangeListener должен срабатывать всякий раз, когда пользователь изменяет значение и фокусируется на нем (или нажимает Enter). Вы правы, что он не сработает, пока пользователь печатает. - person Michael Myers; 06.10.2010
comment
Да, это проблема, которая у меня есть. Это часть панели мастера, и если пользователь просто выбирает дату и нажимает «Далее», то фокус не теряется и метод проверки срабатывает слишком поздно. Спасибо за ваш вклад в любом случае. Кажется, это сложнее, чем казалось на первый взгляд. - person Frank; 06.10.2010
comment
@Frank: я только что попробовал код KeyListener, который вы опубликовали, и видел, что события распечатываются каждый раз, когда я меняю текст своего счетчика. Вы просто ничего не получаете? - person Michael Myers; 06.10.2010
comment
Действительно? Мой ChangeListener работает нормально, но если я сосредоточусь на текстовом поле JSpinner и отредактирую значение вручную, я ничего не получу. Я поставил точки останова на все ключевые события, и ни одно из них не вызывается. Нет выхода. Как добиться успеха с одним и тем же кодом? Это должно быть что-то другое... Только так это может иметь смысл, если твой работает. Спасибо, буду пробовать разные. - person Frank; 06.10.2010

Если вы хотите отключить редактирование клавиатуры, сделайте следующее:

JFormattedTextField tf = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
tf.setEditable(false);

Чтобы прослушивать ключевые события, вам нужно добавить прослушиватель в текстовое поле. Это работает для меня:

((JSpinner.DefaultEditor)spinner.getEditor()).getTextField().addKeyListener(new KeyListener(){

            @Override
            public void keyPressed(KeyEvent e) {                    
            }

            @Override
            public void keyReleased(KeyEvent e) {
                System.out.println("PRESSED!");                    
            }

            @Override
            public void keyTyped(KeyEvent e) {                    
            }

        });
person dogbane    schedule 06.10.2010
comment
Да, спасибо за это. У меня есть это как последний вариант, если мне нужно, но я бы предпочел, чтобы у пользователя был полный доступ для редактирования даты с помощью элементов управления или вручную с помощью клавиатуры. - person Frank; 06.10.2010
comment
Спасибо, но у меня уже был этот код - я обновил вопрос, чтобы показать весь используемый код. Извини за это. - person Frank; 06.10.2010

Это недостаток свинга, и, на мой взгляд, JSpinner должен следовать JComboBox, предоставляя следующий доступ к основному текстовому полю:

JComboBox.getEditor().getEditorComponent()

Изучив источник J1.7, я обнаружил, что вы можете добиться почти того же самого с помощью

JSpinner.getEditor().getComponent(0)

Поэтому вы можете «взломать» слушателя следующим образом:

JSpinner.getEditor().getComponent(0).addKeyListener(...)

Очевидно, это зависит от реализации свинг "под прикрытием" и работает так же, как в J1.7, но нет гарантии, что это работает для других будущих или прошлых версий.

Наслаждаться.

ИЗМЕНИТЬ

или если редактор является экземпляром DefaultEditor, вы можете привести его как таковой и использовать 'getTextField()'. Было бы удобно, если бы это было определено в интерфейсе.

person pstanton    schedule 09.04.2013