A maneira correta de esperar por cordas para tornar-se igual
-
22-07-2019 - |
Pergunta
Em um aplicativo swing um método deve continuar somente depois usuário insere uma resposta correta. A resposta correta é armazenado em uma String com a resposta do usuário sendo definido por um ouvinte para outra cadeia. Assim, o código é
while (!correctAnswer.equals(currentAnswer)) {
// wait for user to click the button with the correct answer typed into the textfield
}
// and then continue
Está tudo bem com esta abordagem ou você de alguma forma refatorar-lo? Não lhe impor penalidade extra na CPU? Aqui está um pouco semelhante pergunta .
Solução
Você é novo na programação UI? A razão que eu peço é que sua resposta baseia-se em um estilo de procedimento de codificação, o que não é o que UIs são. Ela tende a ser orientada a eventos.
Neste caso, a solução é muito fácil: adicionar um ouvinte de evento (ActionListener) para o botão enviar e verificar o resultado lá. Se o seu OK, vá em frente. Se não, digamos assim e deixá-los tente novamente.
Outras dicas
Como já foi sugerido, você vai querer usar atribuir um ouvinte para o botão, que será chamado quando o botão é pressionado.
Aqui está um exemplo incompleta ilustrando como usar um ActionListener
e implementação da sua actionPerformed
método que é chamado quando o botão é pressionado:
...
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.");
}
});
...
Você pode apenas querer implementar ActionListener
na classe onde o botão e de campo de texto reside, assim você não precisa declarar os dois objetos como final
. (Eu usei apenas uma classe interna anônima para manter o exemplo curta.)
Para obter mais informações, você pode querer dar uma olhada em Como escrever um Ação Listener de os tutoriais Java .
Além disso, para obter informações gerais sobre como os eventos funcionam em Java, a Lição:. Ouvintes Escrita eventos com os tutoriais de Java pode ser útil
Editar:. Mudou a expressão dentro declaração if
de textField.getText().equals("some text")
para "some text".equals(textField.getText())
, a fim de evitar uma NullPointerException
se textField
foi null
, por sugestão do comentário do Sr. Brilhante e Nova
Eu não acho que eu recebo a lógica lá, mas me lembra velhos tempos básicos ... :-) Eu não vejo por que as forças de aplicativos que o usuário digite algo já conhecido (a menos que seja uma senha ou algo assim).
Você escreve a digitação é observado por um ouvinte. Então por que não fazer o teste lá? Não faça um loop de espera para um evento, deixe Java fazê-lo (e outras coisas). Se necessário, quebrar a sua lógica em duas, e ir para a segunda parte quando você detectar a entrada correta é dada no ouvinte.
Espero que isso faz sentido ...; -)
Sim, como todos aqui.
Para uma aplicação GUI a melhor maneira de entrada do usuário alça é de esperar por um evento para ser disparado.
Em seguida, um método poderia ser usado para validar a entrada e se ter sucesso você pode continuar com o fluxo, que pode ser ir para outra página.
Aqui está uma (mas simples) exemplo completo de uma tela de login, que valida a entrada do usuário e se ter sucesso executa alguma ação.
Este código não tem outro valor diferente de show em uma completa pronto para ser executado amostra como este conceito é aplicado.
simples gui 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("");
}
}
}
Se as cordas são provenientes de um usuário humano com taxas de GUI, há muito pouco ponto na otimização do desempenho. O ser humano não será capaz de entrar mais do que talvez um a três cordas por segundo, e isso não é nada para a máquina.
Neste caso particular, onde você precisa fazer coisas para obter uma entrada para teste, eu sugiro usar um loop do-while
.