ArrayIndexOutOfBoundsException - 在我的方法

时间:2017-09-13 20:08:11

标签: java exception arraylist methods

我正试图找出我在代码中出错的地方,但我无法摆脱它。

我正在写一个简单的Hangman游戏代码。 它似乎工作,直到在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。

我很感激小费。 谢谢!

HERE'S LINE 97:

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

1 个答案:

答案 0 :(得分:1)

您正在创建sfondi数组,如下所示:

sfondi = new ImageIcon[sfondoCount + 1];

sfondoCount设置为0且从未更改,因此sfondi将始终是1个元素数组(因此唯一有效的索引将是sfondi[0])。之后,你这样做:

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

在执行此语句之前,sfondoUsato0但由于您使用的是前缀增量,因此在使用其值之前它将递增,因此您将最终得到:

labelSfondo.setIcon(sfondi[1]);

我们已经确定sfondi[0]是唯一有效的索引。