Domanda

In un'app Swing un metodo dovrebbe continuare solo dopo che l'utente ha inserito una risposta corretta. La risposta corretta è memorizzata in una stringa con la risposta dell'utente impostata da un ascoltatore su un'altra stringa. Quindi, il codice è

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

Va ??tutto bene con questo approccio o lo rifaresti in qualche modo? Non impone penalità extra alla CPU? Ecco un po ' domanda simile .

È stato utile?

Soluzione

Sei nuovo nella programmazione dell'interfaccia utente? Il motivo per cui ti chiedo è che la tua risposta è basata su uno stile procedurale di codifica, che non è quello di cui si occupano le interfacce utente. Tende ad essere guidato dagli eventi.

In questo caso la soluzione è piuttosto semplice: aggiungi un listener di eventi (ActionListener) al pulsante di invio e controlla il risultato lì. Se è OK, continua. In caso contrario, dillo e lascialo riprovare.

Altri suggerimenti

Come altri hanno suggerito, ti consigliamo di assegnare un ascoltatore al pulsante, che verrà chiamato quando viene premuto il pulsante.

Ecco un esempio incompleto che illustra come utilizzare un ActionListener e implementando il suo metodo actionPerformed che viene chiamato quando si preme il pulsante:

...
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.");
    }
});
...

Potresti voler implementare < code> ActionListener nella classe in cui risiedono il pulsante e il campo di testo, quindi non è necessario dichiarare i due oggetti come final . (Ho appena usato una classe interna anonima per mantenere breve l'esempio.)

Per ulteriori informazioni, potresti dare un'occhiata a Come scrivere un listener di azioni da Tutorial Java .

Inoltre, per informazioni generali sul funzionamento degli eventi in Java, Lezione: scrivere ascoltatori di eventi da The Java Tutorials può essere utile.

Modifica: ha cambiato l'espressione all'interno dell'istruzione if da textField.getText (). è uguale (" del testo ") a " alcuni testi " .equals (textField.getText ()) per evitare un NullPointerException se textField era null , per suggerimento dal commento di Mr. Shiny e New.

Non credo di avere la logica lì, ma mi ricorda i vecchi tempi di base ... :-) Non vedo perché l'applicazione costringe l'utente a digitare qualcosa di già noto (a meno che non sia una password o qualcosa del genere).

Scrivi che la digitazione viene osservata da un ascoltatore. Quindi perché non fare il test lì? Non fare un loop in attesa di un evento, lascia che Java lo faccia (e altre cose). Se necessario, spezza la tua logica in due e vai alla seconda parte quando rilevi che l'input corretto è dato nel listener.

Spero che abbia senso ... ;-)

Sì, come hanno detto tutti qui.

Per un'app gui il modo migliore per gestire l'input dell'utente è attendere che un evento venga generato.

Quindi è possibile utilizzare un metodo per convalidare l'input e, in caso di successo, è possibile continuare con il flusso, che potrebbe essere indirizzato a un'altra pagina.

Ecco un esempio completo (ma semplice) di una schermata di accesso, che convalida l'input dell'utente e se riesce esegue qualche azione.

Questo codice non ha altro valore che mostrare in un esempio completo pronto per l'esecuzione come viene applicato questo concetto.

gui semplice 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 le tue stringhe provengono da un utente umano a frequenze GUI, c'è ben poco senso nell'ottimizzazione delle prestazioni. L'umano non sarà in grado di inserire più di forse da una a tre stringhe al secondo, e questo non è niente per la macchina.

In questo caso particolare, dove è necessario fare cose per ottenere un input da testare, suggerirei di usare un do-while loop.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top