0

I have a small piece of code designed to draw a card when a button is clicked. As of now I get the following error (among others) when I active actionPerformed(): Exception in thread "AWT-EventQueue-0 java.lang.IndexOutOfBoundsException...". I'm completely new to this so forgive me if it's a simple mistake.

import java.awt.*;
import java.awt.event.*;
import java.util.*; /*Used for Random and ArrayList*/
public class AL extends Frame implements WindowListener,ActionListener {
    TextField text = new TextField(20);
    Button b;
    private int numClicks = 0;
    private static ArrayList<Card> deck=new ArrayList<Card>();
    private static ArrayList<Card> playerOneDeck=new ArrayList<Card>();
    private static ArrayList<Card> playerTwoDeck=new ArrayList<Card>();



    public static void main(String[] args) {
            AL myWindow = new AL("Well of course you know, this means WAR!");
            myWindow.setSize(350,100);
            myWindow.setVisible(true);
            ArrayList<Card> playerTwoDeck=new ArrayList<Card>();
    }//end main()

    public AL(String title) {

            super(title);
            setLayout(new FlowLayout());
            addWindowListener(this);
            b = new Button("Draw");
            add(b);
            add(text);
            b.addActionListener(this);
            ArrayList<Card> deck=new ArrayList<Card>();
            ArrayList<Card> playerOneDeck=new ArrayList<Card>();
            deck=initializeDeck();
            Collections.shuffle(deck);
    }

    public void actionPerformed(ActionEvent e) {
            numClicks++;
            Card theCard=playerOneDeck.get(0);
            text.setText(theCard.name);
            text.setText(theCard.name);
    }

    public void windowClosing(WindowEvent e) {
            dispose();
            System.exit(0);
    }
    /*Assign names, values, and suits to all of the Card objects.*/
    public static ArrayList<Card> initializeDeck() {
        Card[] tempDeck=new Card[52];
        ArrayList<Card> completeDeck=new ArrayList<Card>();
        for (int i=0; i<tempDeck.length; i++) {
            tempDeck[i]=new Card();
            tempDeck[i].name="Two";
            tempDeck[i].value=2;
            i++;
            tempDeck[i]=new Card();
            tempDeck[i].name="Three";
            tempDeck[i].value=3;
            i++;
            tempDeck[i]=new Card();
            tempDeck[i].name="Four";
            tempDeck[i].value=4;
            i++;
            tempDeck[i]=new Card();
            tempDeck[i].name="Five";
            tempDeck[i].value=5;
            i++;
            tempDeck[i]=new Card();
            tempDeck[i].name="Six";
            tempDeck[i].value=6;
            i++;
            tempDeck[i]=new Card();
            tempDeck[i].name="Seven";
            tempDeck[i].value=7;
            i++;
            tempDeck[i]=new Card();
            tempDeck[i].name="Eight";
            tempDeck[i].value=8;
            i++;
            tempDeck[i]=new Card();
            tempDeck[i].name="Nine";
            tempDeck[i].value=9;
            i++;
            tempDeck[i]=new Card();
            tempDeck[i].name="Ten";
            tempDeck[i].value=10;
            i++;
            tempDeck[i]=new Card();
            tempDeck[i].name="Jack";
            tempDeck[i].value=11;
            i++;
            tempDeck[i]=new Card();
            tempDeck[i].name="Queen";
            tempDeck[i].value=12;
            i++;
            tempDeck[i]=new Card();
            tempDeck[i].name="King";
            tempDeck[i].value=13;
            i++;
            tempDeck[i]=new Card();
            tempDeck[i].name="Ace";
            tempDeck[i].value=14;
        }//end FOR
        /*Assign suits*/
        /*keep in mind that the array is now [2], [3],..[k],[a],[2],[3],[k],[a],etc */
        for (int j=0; j<tempDeck.length; j++) {
            tempDeck[j].suit="Hearts";
            j++;
            tempDeck[j].suit="Diamonds";
            j++;
            tempDeck[j].suit="Spades";
            j++;
            tempDeck[j].suit="Clubs";
        }//end FOR

        for (int k=0; k<tempDeck.length;k++) {
            completeDeck.add(tempDeck[k]);
        }
        return completeDeck;
    }//end initializeDeck()

    public void windowOpened(WindowEvent e) {}
    public void windowActivated(WindowEvent e) {}
    public void windowIconified(WindowEvent e) {}
    public void windowDeiconified(WindowEvent e) {}
    public void windowDeactivated(WindowEvent e) {}
    public void windowClosed(WindowEvent e) {}

}//end AL class

eggHunter
  • 389
  • 2
  • 4
  • 15
  • 2
    1) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve). 2) Use a consistent and logical indent for code blocks. The indentation of the code is intended to help people understand the program flow. 3) Using `static` is usually unnecessary, and has a bad code smell. – Andrew Thompson Jan 21 '14 at 18:52
  • Which line does the stack trace say the exception occurs on? – Kayaman Jan 21 '14 at 18:53
  • BTW - Why AWT rather than Swing? See my answer on [Swing extras over AWT](http://stackoverflow.com/a/6255978/418556) for many good reasons to abandon using AWT components. – Andrew Thompson Jan 21 '14 at 18:53
  • Card theCard=playerOneDeck.get(0); – eggHunter Jan 21 '14 at 18:59

1 Answers1

1

You try to get the first element from PlayerOneDeck in the first line of ActionPerformed: Card theCard=playerOneDeck.get(0); However, PlayerOneDeck is an empty ArrayList. It has no elements, so trying to get an element from it returns the IndexOutOfBoundsException.

You initialize both a class variable PlayerOneDeck and also a variable in your constructor of the same name. It's possible you fill the constructor variable with elements, but actionPerformed calls the class variable, which remains empty. For example:

public class Main {
    ArrayList<Integer> array = new ArrayList<Integer>();  // class variable

    public static void main(String[] args) {
        ArrayList<Integer> array = new ArrayList<Integer>();  // method variable, overrides class variable within the main method
        array.add(1);  // adds 1 to the method variable
        (new Main()).printArray();
    }

    public void printArray() {
        System.out.println(array.get(0));  // tries to print the first element of class variable, throws IndexOutOfBoundsException
    }
}

Remove your local variable and use only the global class one and your problem may go away.

asaini007
  • 858
  • 5
  • 19
  • My apologizes, I had copy-and-pasted an old version. PlayOneDeck now has contents. – eggHunter Jan 21 '14 at 19:03
  • I have a GUI-less version that works fine so I know the logic is correct. – eggHunter Jan 21 '14 at 19:04
  • 1
    I notice you have a class variable `PlayerOneDeck` and and also instantiate a variable of the same name in your `main` method. It's possible you tried to fill that method variable with elements, but `actionPerformed` uses the class instance variable, which would remain empty. – asaini007 Jan 21 '14 at 19:10
  • I moved the deck and playerOneDeck-related methods to public AL() and am still getting the same error. – eggHunter Jan 21 '14 at 19:17
  • 1
    @eggHunter If your code is different than that you posted in your question, I recommend you update it. And fix what I suggested, and see if that helps. – asaini007 Jan 21 '14 at 19:20
  • @eggHunter You still have variables of the same name and type as global class variables `deck`, `playerOneDeck`, and `playerTwoDeck` within your methods (the constructor and main method)... that's a problem. – asaini007 Jan 21 '14 at 19:30