Получение ENTER для работы с JSpinner, как это происходит с JTextField - PullRequest
5 голосов
/ 19 декабря 2008

Во-первых, чтобы упростить объяснение моей работы, вот мой код:

JSpinner spin = new JSpinner();
JFormattedTextField text = getTextField(spin);

text.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
            // Do stuff...
    }
});

...

private JFormattedTextField getTextField(JSpinner spinner) {
    JComponent editor = spinner.getEditor();

    if (editor instanceof JSpinner.DefaultEditor) {
        return ((JSpinner.DefaultEditor )editor).getTextField();
    } else {
        System.err.println( "Unexpected editor type: "
                           + spinner.getEditor().getClass()
                           + " isn't a descendant of DefaultEditor" );
        return null;
    }
}

Итак, как вы можете видеть, я зашел так далеко. И действительно, когда я набираю значение в компоненте текстового поля счетчика (JFormattedTextField) и ТОГДА нажимаю ВВОД, это работает.

Теперь я хочу, чтобы текстовое поле отвечало на ENTER без необходимости вручную вводить новое значение (что лишает цель сделать из него спиннер). Как мне это сделать?

Ответы [ 2 ]

4 голосов
/ 19 декабря 2008

Я знаю, что это не слушатель действия ... но, может быть, это может сработать для вас?

<code>
    text.addKeyListener( new KeyAdapter() {
            @Override
            public void keyReleased( final KeyEvent e ) {
                if ( e.getKeyCode() == KeyEvent.VK_ENTER ) {
                    System.out.println( "enter pressed" );
                }
            }
        } );
1 голос
/ 10 июня 2016

Я сам столкнулся с проблемой, связанной с этим. В моем случае у меня был JSpinner с настройкой SpinnerNumberModel, чтобы я мог вводить числовые значения идентификаторов, а затем извлекать их из удаленной базы данных. Это хорошо работало с JButton в качестве моего триггера для запроса, но я хотел иметь возможность переключать фокус на поле через Tab и нажимать клавишу ввода, а также иметь возможность изменять значение, вводя идентификатор с помощью цифровых клавиш , затем нажмите Enter.

Единственное, что доставляло мне больше всего проблем, - это ввод вручную идентификатора с помощью цифровых клавиш и затем нажатие клавиши ввода. Когда я делал это, запрос все равно выполнялся, но он запрашивал предыдущий идентификатор, а не тот, который я только что ввел, поэтому мне пришлось бы снова нажать клавишу ввода, чтобы запросить новый идентификатор (см. Код)

((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            queryData();
        }
    }
});

и метод запроса:

private void queryData() {
    int minVal = Integer.parseInt(minRng.getValue().toString());
    queryDataBase(minVal);
}

Чтобы исправить это, все, что мне нужно было сделать, это заставить запрос ждать, пока он не обновит свое значение, что было легко сделать с помощью SwingUtilities.invokeLater(), чтобы принудительно завершить его в конец очереди EDT, как так:

((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    queryData();
                }
            });
        }
    }
});

Благодаря invokeLater() запрос теперь выполняется по новому значению, а не по предыдущему, при нажатии enter, поскольку JSpinner затем обновил свое значение до вновь введенного.

Я предполагаю, что причина этого в том, что введенное значение официально не применяется к JSpinner до тех пор, пока вы не нажмете клавишу ввода, что также запускает прослушиватель ключей для запроса. KeyEvent для пользовательского прослушивателя ключа [query] является первым в очереди, поэтому он сначала запускает свой код, а затем KeyEvent для применения значения к JSpinner из внутреннего JFormattedTextField Вот почему он запрашивает старое значение. SwingUtilities.invokeLater() просто помещает сам запрос в конец очереди, поэтому он позволяет другому KeyEvent завершить код перед выполнением запроса.

Edit:

Другой способ добиться этого - запросить значение непосредственно у JFormattedTextField, а не JSpinner, поскольку это также должно вернуть вновь введенное значение, поскольку JFormattedTextField содержит введенное вами значение, но оно не имеет еще не были переданы JSpinner, который, как представляется, в чем проблема.

private void queryData() {
    JFormattedTextField tf = ((JSpinner.DefaultEditor) minRng.getEditor()).getTextField();
    int minVal = Integer.parseInt(tf.getText());
    queryDataBase(minVal);
}

Единственная проблема с этим методом заключается в том, что вам нужно перехватить любые NumberFormatException с при анализе значения, когда подход SwingUtilities.invokeLater() позволяет моделируемой спиннеру автоматически удалять любые недопустимые символы и продолжать выполнение запроса. .

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

...