Правильный способ ожидания, чтобы строки стали равными - PullRequest
0 голосов
/ 02 декабря 2008

В приложении Swing метод должен продолжаться только после того, как пользователь введет правильный ответ. Правильный ответ сохраняется в строке, а ответ пользователя задается слушателем для другой строки. Итак, код

while (!correctAnswer.equals(currentAnswer)) {
         // wait for user to click the button with the correct answer typed into the textfield
}
// and then continue

Все ли в порядке с этим подходом или вы как-то его рефакторинг? Разве это не накладывает дополнительный штраф на процессор? Вот несколько похожий вопрос .

Ответы [ 5 ]

6 голосов
/ 02 декабря 2008

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

Вот неполный пример, иллюстрирующий использование ActionListener и реализацию его actionPerformed метода, который вызывается при нажатии кнопки:

...
final JTextField textField = new JTextField();
final JButton okButton = new JButton("OK");
okButton.addActionListner(new ActionListener() {
    public void actionPerformed(ActionEvent e)
    {
        if ("some text".equals(textField.getText()))
            System.out.println("Yes, text matches.");
        else
            System.out.println("No, text does not match.");
    }
});
...

Возможно, вы просто захотите внедрить ActionListener в классе, где находятся кнопка и текстовое поле, поэтому вам не нужно объявлять два объекта как final. (Я просто использовал анонимный внутренний класс для краткости примера.)

Для получения дополнительной информации вы можете взглянуть на Как написать слушатель действий из Учебники по Java .

Кроме того, для получения общей информации о том, как события работают в Java, может пригодиться Урок: Написание прослушивателей событий из Учебников Java.

Редактировать: Изменено выражение внутри оператора if с textField.getText().equals("some text") на "some text".equals(textField.getText()), чтобы исключить NullPointerException, если textField было null, по предложению мистера Шини и новый комментарий.

5 голосов
/ 02 декабря 2008

Вы новичок в программировании пользовательского интерфейса? Причина, по которой я спрашиваю, состоит в том, что ваш ответ основан на процедурном стиле кодирования, а это не то, для чего предназначены интерфейсы Он, как правило, определяется событиями.

В этом случае решение довольно простое: добавьте прослушиватель событий (ActionListener) к кнопке отправки и проверьте результат там. Если все в порядке, продолжайте. Если нет, то скажите, и пусть они попробуют снова.

2 голосов
/ 03 декабря 2008

Да, как все говорили здесь.

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

Затем можно использовать метод для проверки ввода, и в случае успеха вы можете продолжить поток, который может перейти на другую страницу.

Вот полный (но простой) пример экрана входа в систему, который проверяет вводимые пользователем данные и в случае успеха выполняет какое-либо действие.

Этот код не имеет никакого другого значения, кроме показанного в полном готовом к запуску примере , как применяется эта концепция.

простой графический интерфейс http://img229.imageshack.us/img229/1532/simplenz0.png

// * used for brevity. Preffer single class per import
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.net.*;
import java.io.*;


public class MatchString{

    private final JTextField password;
    private final JFrame frame;

    public static void main( String [] args ){
        MatchString.show();
    }

    public static void show(){
        SwingUtilities.invokeLater( new Runnable(){
            public void run(){
                new MatchString();
            }
        });
    }

    private MatchString(){
        password = new JPasswordField( 20 );
        frame = new JFrame("Go to www.stackoverflow");
        init();
        frame.pack();
        frame.setVisible( true );
    }


    private void init(){

        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

        frame.add( new JPanel(){{
            add( new JLabel("Password:"));
            add( password );
        }});

        // This is the key of this question.
        // the password textfield is added an 
        // action listener
        // When the user press enter, the method 
        // validatePassword() is invoked.
        password.addActionListener( new ActionListener(){
            public void actionPerformed( ActionEvent e ) {
                validatePassword();
            }
        });
    }


    private void validatePassword(){            
        // If the two strings match
        // then continue with the flow
        // in this case, open SO site.    
        if ( "stackoverflow".equals(password.getText())) try {
            Desktop.getDesktop().browse( new URI("http://stackoverflow.com"));
            frame.dispose();
        } catch ( IOException ioe ){
            showError( ioe.getMessage() );
        } catch ( URISyntaxException use ){
            showError( use.getMessage() );
        } else {
            // If didn't match.. clear the text.
            password.setText("");
        }
    }
 }
2 голосов
/ 02 декабря 2008

Не думаю, что я понимаю логику, но она напоминает мне о старых базовых временах: :-) Я не понимаю, почему приложение заставляет пользователя вводить что-то уже известное (если это не пароль или что-то).

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

Надеюсь, это имеет смысл ...; -)

0 голосов
/ 02 декабря 2008

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

В этом конкретном случае, когда вам нужно что-то сделать, чтобы получить входные данные для тестирования, я бы предложил использовать цикл <a href="http://java.sun.com/docs/books/tutorial/java/nutsandbolts/while.html" rel="nofollow noreferrer">do-while</a>.

...