2016-01-13 19 views
5

Ho appena iniziato ad apprendere la GUI Java e ho affrontato questo problema mentre praticavo la gestione degli eventi. Here's the initial windowCosa c'è di sbagliato con questo codice di Java GUI?

Quando inserisco un numero all'interno del campo di testo, è necessario dire se il numero indovinato è più alto, più basso o abbinato. Se non corrisponde, richiederebbe un altro numero. Ma la finestra si blocca appena. After entering data

Immagino che cada in un ciclo infinito. Ecco il codice. Aiutami a capire dove si trova il problema. Grazie.

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class RandomNumGame extends JFrame { 
    private JLabel promptLabel, resultLabel, answerLabel; 
    private int tries=1, randomNum, guessNum; 
    private JButton button; 
    private JTextField txt; 
    private boolean guessed; 

    public RandomNumGame() { 
     setLayout(new FlowLayout()); 

     promptLabel = new JLabel("Guess a number(1-1000): "); 
     add(promptLabel); 

     txt = new JTextField(7); 
     add(txt); 

     button = new JButton("Guess!"); 
     add(button); 

     resultLabel = new JLabel(""); 
     add(resultLabel); 

     /*answerLabel = new JLabel(""); 
     add(answerLabel); 
     */ 

     Event e = new Event(); 
     button.addActionListener(e); 
    } 

    private class Event implements ActionListener{ 
     public void actionPerformed(ActionEvent e){ 
      randomNum = (int)(Math.random() * 1000 + 1); 
      guessed=false; 
      do{ 
       try{ 
        guessNum = (int)(Double.parseDouble(txt.getText())); 
        if(guessNum>randomNum){ 
         resultLabel.setText("Your number is higher. Try Again"); 
        } 
        else if(guessNum<randomNum){ 
         resultLabel.setText("Your number is lower. Try Again"); 
        } 
        else{ 
         resultLabel.setText("Your number matched!"); 
         guessed=true; 
        } 
       } 
       catch(Exception ee){ 
        resultLabel.setText("Enter a legit number. What are you stupid?"); 
       } 
      }while(!guessed); 

     } 
    } 

    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     RandomNumGame ran = new RandomNumGame(); 
     ran.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     ran.setSize(300, 120); 
     //ran.pack(); 
     ran.setVisible(true); 
     ran.setTitle("Random Number Game"); 
    } 

} 

risposta

2

non è necessario un ciclo nel metodo actionPerformed. Fatelo eseguire una sola volta e controllate se è stato indovinato subito dopo. Sei semplicemente bloccato nel ciclo quando è stato inserito un numero sbagliato dall'utente. Per ottenerlo più liscio, crea il numero casuale solo quando guessed è true ed esegui solo una volta l'ipotesi e le condizioni.

// Change constructor 
public RandomNumGame() { 
    ... 
    guessed = true; // initialize to true to create a new number when you click 
} 
private class Event implements ActionListener{ 
    public void actionPerformed(ActionEvent e){ 
     if(guessed) { // If the number was guessed, on the next click you get a new random number 
      randomNum = (int)(Math.random() * 1000 + 1); 
      guessed = false; 
     } 
     try{ 
      guessNum = (int)(Double.parseDouble(txt.getText())); 
      if(guessNum>randomNum){ 
       resultLabel.setText("Your number is higher. Try Again"); 
      } 
      else if(guessNum<randomNum){ 
       resultLabel.setText("Your number is lower. Try Again"); 
      } 
      else{ 
       resultLabel.setText("Your number matched! Click again for a new Number"); 
       guessed=true; 
      } 
     } 
     catch(Exception ee){ 
      resultLabel.setText("Enter a legit number. What are you stupid?"); 
     } 
    } 
} 
+0

Grazie mille. Questo ha fatto il trucco. –

0

tuo numero casuale e l'immissione di testo sarà lo stesso fino a loop. Presumo che il valore non cada in altre condizioni in cui guessed diventa true. o hai richiesto di aggiungere un'istruzione di generazione di numeri casuali nel ciclo while. cioè

do{ 
randomNum = (int)(Math.random() * 1000 + 1); //It required here 
try{ 
        guessNum = (int)(Double.parseDouble(txt.getText())); 
        if(guessNum>randomNum){ 
         resultLabel.setText("Your number is higher. Try Again"); 
        } 
        else if(guessNum<randomNum){ 
         resultLabel.setText("Your number is lower. Try Again"); 
        } 
        else{ 
         resultLabel.setText("Your number matched!"); 
         guessed=true; 
        } 
       } 
       catch(Exception ee){ 
        resultLabel.setText("Enter a legit number. What are you stupid?"); 
       } 
      }while(!guessed); 
+0

Il numero casuale dovrebbe rimanere lo stesso all'interno del ciclo, ma come posso cambiare l'input di testo dopo ogni ciclo? –

+0

Secondo il vostro requisito. perché provi con loop? basta rimuovere o. funzionerà come previsto. – iMBMT

2

Il quadro GUI ha il proprio ciclo di evento, e trattare l'evento (comprese le risposte ai testo di input, pressione del tasto ecc) saranno bloccati mentre codice utente sta eseguendo. Vuoi che il tuo gestore di eventi finisca il più rapidamente possibile.

Struttura come, ogni volta che si preme il pulsante, viene valutata l'ipotesi corrente, i messaggi vengono visualizzati e il gestore termina. Tra un pulsante e l'altro, il programma mantiene il conteggio delle supposizioni, il numero da indovinare, ecc.

1

Non si dovrebbe leggere ciò che l'utente scrive su un ciclo. Il tuo ascoltatore di eventi sul pulsante di ricerca dovrebbe solo verificare se il numero è più alto o più basso una volta e poi fermarsi. Sarà richiamato ogni volta che l'utente preme il pulsante. Il modo in cui è ora, a parte gli altri problemi che possono esserci, è che lo controlla una volta e rimane in un controllo continuo per sempre fino a quando non è corretto. La sua programmazione non è pratica e cattiva perché consumerà molta CPU in attesa attiva in quel modo.

1

Hai ragione, è il problema del ciclo. Se il primo numero inserito non corrisponde a randomNum, la variabile guessed non sarà mai impostata su true. Suggerisco di fare quanto segue:

  1. non inizializzare randomNum all'interno del gestore di eventi. Fallo nel costruttore.
  2. rimuovere do{...} while(!guessed). Non hai bisogno del loop qui, semplicemente estrai la logica che hai all'interno del loop ora
+0

Sì, questo ha aiutato a uscire dal ciclo. Ma volevo anche che generasse un altro numero dopo che l'utente ha indovinato. –

+0

In tal caso, è possibile inizializzare nuovamente il numero casuale all'interno dell'ultima clausola 'else', dove ora si ha' guessed = true' – vdjurovic

Problemi correlati