2017-09-13 71 views
-1

我想弄清楚我在代碼中犯了什麼錯誤,但我無法擺脫它。ArrayIndexOutOfBoundsException - 無法找到我的方法中的錯誤

我正在寫一個簡單的Hang子手遊戲代碼。 它似乎工作,直到在JTextArea中鍵入錯誤的字母。 該錯誤似乎位於我的「gioca()」方法中。

這裏是我的代碼:

package giocoimpiccato; 

//Frame in cui si visualizza il gioco. Qui c'è il metodo main. 

import java.util.ArrayList; 
import java.util.Random; 
import javax.swing.ImageIcon; 

//Composto da 1 JLABEL per la foto, 1 JLABEL per il titolo, 1 JLABEL per il 
risultato, 1 JLABEL per le lettere inserite, 1 JLABEL per la parola e 1 
JTEXTAREA per inserire le lettere 
public class GiocoImpiccatoFrame extends javax.swing.JFrame 
{ 
public String parolaDaIndovinare; 
public ArrayList<String> lettereUsate; //uso un vettore perchè ha grandezza variabile 
public int tentativi = 6; 
public ArrayList<Integer> lettereTrovate; 
public int sfondoCount = 0; 
public ImageIcon[] sfondi; //uso un array perchè ha grandezza fissa 
public int sfondoUsato = 0; 
public String lettUsate = ""; 

//costruttore 
public GiocoImpiccatoFrame() 
{ 
    lettereTrovate = new ArrayList<Integer>(); 
    lettereUsate = new ArrayList<String>(); 
    parolaDaIndovinare = leggiParola(); 
    sfondi = new ImageIcon[sfondoCount + 1]; 
    for(int i=0; i<sfondoCount; i++) 
    { 
     ImageIcon file = new javax.swing.ImageIcon(getClass().getResource("/albero" + i + ".jpg")); 
     sfondi[i] = file; 
    } 

    initComponents(); 
    setLocationRelativeTo(null); //per far apparire il frame in centro allo schermo 

    labelSfondo.setIcon(sfondi[0]); 
} 

//metodo che estrae casualmente una parola dall'array 
public String leggiParola() 
{ 
    Random r = new Random(); 
    int idx = 0; 
    String parola = ""; 

    String[] parole = new String[10]; 
    parole[0] = "cane"; 
    parole[1] = "gatto"; 
    parole[2] = "pescespada"; 
    parole[3] = "frutta"; 
    parole[4] = "videogioco"; 
    parole[5] = "sentinella"; 
    parole[6] = "oviparo"; 
    parole[7] = "ateneo"; 
    parole[8] = "poltrona"; 
    parole[9] = "fucina"; 

    idx = r.nextInt(parole.length - 1); 
    parola = parole[idx]; 

    return parola; 
} 

//controlla le lettere inserite, le confronta con quelle della parola e le inserisce (tramite metodo visualizzazioneParola) e segna gli errori 
public void gioca(String c) 
{ 
    boolean fine = false; 
    boolean nonUsato = true; 
    boolean trovato = false; 

    if (c.length() == 1) 
    { 
     for (String lettUsata : lettereUsate) //ciclo for che percorre tutto un array e assegna alla variabile lettUsata ogni volta un valore dell'array fino a farli tutti 
     { 
      if ((c.toUpperCase()).equals(lettUsata.toUpperCase())) // equals per le stringhe - toUpperCase trasforma tutto in maiuscole per il confronto 
      { 
       nonUsato = false; 
       break; 
      } 
     } 

     if (nonUsato) 
     { 
      lettereUsate.add(c); 
      lettUsate = lettUsate + " " + c; 
      trovato = cerca(c.charAt(0)); 
      if (trovato) 
      { 
       labelParola.setText(visualizzazioneParola()); 
       fine = haiVinto(); 
      } 
      else 
      { 
       tentativi--; 
       labelSfondo.setIcon(sfondi[++sfondoUsato]); 
      } 
     } 
    } 
} 

//metodo che restituisce una variabile booleana dopo aver confrontato il carattere in ingresso con quelli della parola da indovinare 
public boolean cerca(char c) 
{ 
    boolean trovato = false; 

    for (int i = 0; i < parolaDaIndovinare.length(); i++) 
    { 
     if (Character.toLowerCase(parolaDaIndovinare.charAt(i)) == Character.toLowerCase(c)) 
     { 
      lettereTrovate.add(i); 
      trovato = true; 
     } 
    } 

    return trovato; 
} 

//metodo che restituisce una variabile booleana per la vittoria 
public boolean haiVinto() 
{ 
    if (parolaDaIndovinare.length() == lettereTrovate.size()) 
    { 
     labelParola.setText(visualizzazioneParola()); 
     labelRisultato.setText("Hai Vinto!"); 
     txtInput.setEnabled(false); 
     return true; 
    } 
    else 
    { 
     return false; 
    } 
} 

// inserisce le lettere alla posizione corretta o la lineetta in caso di lettera ancora da indovinare 
public String visualizzazioneParola() 
{ 
    String str = ""; 
    boolean trovato = false; 

    for (int i = 0; i < parolaDaIndovinare.length(); i++) 
    { 
     trovato = false; 

     for (int j : lettereTrovate) 
     { 
      if (j == i) 
      { 
       str = str + parolaDaIndovinare.charAt(i); 
       trovato = true; 
       break; 
      } 
     } 

     if (trovato == false) 
     { 
      str = str + "_"; 
     } 

     if (i != parolaDaIndovinare.length()-1) 
     { 
      str = str + " "; 
     } 
    } 

    return str; 
} 

/** 
* This method is called from within the constructor to initialize the form. 
* WARNING: Do NOT modify this code. The content of this method is always 
* regenerated by the Form Editor. 
*/ 
@SuppressWarnings("unchecked") 
// <editor-fold defaultstate="collapsed" desc="Generated Code">       
private void initComponents() { 

    labelTitolo = new javax.swing.JLabel(); 
    labelLettere = new javax.swing.JLabel(); 
    labelParola = new javax.swing.JLabel(); 
    labelRisultato = new javax.swing.JLabel(); 
    txtInput = new javax.swing.JTextField(); 
    labelSfondo = new javax.swing.JLabel(); 

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
    setTitle("Il Gioco dell'Impiccato"); 
    setMinimumSize(new java.awt.Dimension(1000, 600)); 
    setSize(new java.awt.Dimension(1000, 600)); 
    getContentPane().setLayout(null); 

    labelTitolo.setFont(new java.awt.Font("Copperplate Gothic Light", 1, 36)); // NOI18N 
    labelTitolo.setForeground(new java.awt.Color(255, 0, 0)); 
    labelTitolo.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); 
    labelTitolo.setText("Il Gioco dell'Impiccato"); 
    getContentPane().add(labelTitolo); 
    labelTitolo.setBounds(156, 6, 662, 94); 

    labelLettere.setFont(new java.awt.Font("Arial", 1, 24)); // NOI18N 
    labelLettere.setForeground(new java.awt.Color(255, 0, 0)); 
    labelLettere.setText(lettUsate); 
    getContentPane().add(labelLettere); 
    labelLettere.setBounds(6, 146, 470, 64); 

    labelParola.setFont(new java.awt.Font("Copperplate Gothic Light", 1, 36)); // NOI18N 
    labelParola.setForeground(new java.awt.Color(255, 0, 0)); 
    labelParola.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); 
    labelLettere.setText(visualizzazioneParola()); 

    labelLettere.setToolTipText(parolaDaIndovinare); 
    getContentPane().add(labelParola); 
    labelParola.setBounds(6, 410, 651, 78); 

    labelRisultato.setFont(new java.awt.Font("Copperplate Gothic Light", 1, 36)); // NOI18N 
    labelRisultato.setForeground(new java.awt.Color(255, 0, 0)); 
    labelRisultato.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); 
    getContentPane().add(labelRisultato); 
    labelRisultato.setBounds(6, 506, 812, 88); 

    txtInput.setFont(new java.awt.Font("Arial", 1, 24)); // NOI18N 
    txtInput.setForeground(new java.awt.Color(255, 0, 0)); 
    txtInput.setHorizontalAlignment(javax.swing.JTextField.CENTER); 
    txtInput.addActionListener(new java.awt.event.ActionListener() { 
     public void actionPerformed(java.awt.event.ActionEvent evt) { 
      txtInputActionPerformed(evt); 
     } 
    }); 
    getContentPane().add(txtInput); 
    txtInput.setBounds(6, 262, 142, 91); 

    labelSfondo.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); 
    getContentPane().add(labelSfondo); 
    labelSfondo.setBounds(0, 0, 1000, 600); 

    pack(); 
}// </editor-fold>       

private void txtInputActionPerformed(java.awt.event.ActionEvent evt) {           
    // TODO add your handling code here: 
    gioca(txtInput.getText()); 

    if(tentativi==0) 
    { 
     labelRisultato.setText("HAI PERSO: la parola era '" + parolaDaIndovinare.toUpperCase() + "'"); 
     txtInput.setEnabled(false); 
    } 

    txtInput.setText(""); 
    labelLettere.setText(lettUsate); 
}           

/** 
* @param args the command line arguments 
*/ 
public static void main(String args[]) { 
    /* Set the Nimbus look and feel */ 
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. 
    * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
    */ 
    try { 
     for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
      if ("Nimbus".equals(info.getName())) { 
       javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
       break; 
      } 
     } 
    } catch (ClassNotFoundException ex) { 
     java.util.logging.Logger.getLogger(GiocoImpiccatoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (InstantiationException ex) { 
     java.util.logging.Logger.getLogger(GiocoImpiccatoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (IllegalAccessException ex) { 
     java.util.logging.Logger.getLogger(GiocoImpiccatoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
     java.util.logging.Logger.getLogger(GiocoImpiccatoFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
    } 
    //</editor-fold> 

    /* Create and display the form */ 
    java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      new GiocoImpiccatoFrame().setVisible(true); 
     } 
    }); 
} 

// Variables declaration - do not modify      
private javax.swing.JLabel labelLettere; 
private javax.swing.JLabel labelParola; 
private javax.swing.JLabel labelRisultato; 
private javax.swing.JLabel labelSfondo; 
private javax.swing.JLabel labelTitolo; 
private javax.swing.JTextField txtInput; 
// End of variables declaration     
} 

而這裏的例外,它產生的時候我輸錯了一封信:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 1 
at giocoimpiccato.GiocoImpiccatoFrame.gioca(GiocoImpiccatoFrame.java:97) 
at giocoimpiccato.GiocoImpiccatoFrame.txtInputActionPerformed(GiocoImpiccatoFrame.java:240) 

這就像打錯一個字母不能被添加到我的ArrayList lettereUsate。

我會很感激小費。 謝謝!

該處的路線97:

labelSfondo.setIcon(sfondi[++sfondoUsato]); 
+0

哪條線是97線? –

+0

97行是cerca()方法啓動的地方 –

+0

這是不可能的。請編輯您的問題並顯示97行的位置。第97行在你的例外中表示:'at giocoimpiccato.GiocoImpiccatoFrame.gioca(GiocoImpiccatoFrame.java:97)' –

回答

1

您正在創建的sfondi陣列是這樣的:

sfondi = new ImageIcon[sfondoCount + 1]; 

sfondoCount被設置爲0和從未改變,所以sfondi將永遠是一個1個元件陣列(所以唯一有效的索引將是sfondi[0])。後來,你這樣做:這個語句被執行

labelSfondo.setIcon(sfondi[++sfondoUsato]); 

之前,sfondoUsato0但由於您使用的前綴增量,使用它的價值的時候,才遞增,所以你會結束:

labelSfondo.setIcon(sfondi[1]); 

而且我們已經確定sfondi[0]是唯一有效的索引。

+0

那麼你會建議什麼?每當出現錯誤時,我想讓JLabel圖標發生更改。 –