[java] Could someone look at this error?

Started by
3 comments, last by smitty1276 16 years, 11 months ago
Here are the errors:
init:
deps-jar:
Compiling 1 source file to C:\Documents and Settings\James Kovacs\JavaGin\build\classes
C:\Documents and Settings\James Kovacs\JavaGin\src\App.java:76: local variable playerHand is accessed from within inner class; needs to be declared final
                playerHand = DrawCardHandChange(playerHand, DrawCardDiscard(_discardPile));  //should add card from discard to hand
C:\Documents and Settings\James Kovacs\JavaGin\src\App.java:76: local variable playerHand is accessed from within inner class; needs to be declared final
                playerHand = DrawCardHandChange(playerHand, DrawCardDiscard(_discardPile));  //should add card from discard to hand
C:\Documents and Settings\James Kovacs\JavaGin\src\App.java:76: local variable _discardPile is accessed from within inner class; needs to be declared final
                playerHand = DrawCardHandChange(playerHand, DrawCardDiscard(_discardPile));  //should add card from discard to hand
C:\Documents and Settings\James Kovacs\JavaGin\src\App.java:77: local variable _discardPile is accessed from within inner class; needs to be declared final
                _discardPile = DrawCardDiscardChange(_discardPile);  //take top card from discard
C:\Documents and Settings\James Kovacs\JavaGin\src\App.java:77: local variable _discardPile is accessed from within inner class; needs to be declared final
                _discardPile = DrawCardDiscardChange(_discardPile);  //take top card from discard
5 errors
BUILD FAILED (total time: 0 seconds)
And here is the code:
public class App extends javax.swing.JFrame {
    
    /** Creates new form App */
    public App() {
        initComponents(); //creates original state of GUI
        getContentPane().setBackground(new Color(0,102,0)); //paints the ContentPane to match the GUI
        
        int[] _suitDeck = {0,                                           //card number in array corresponds to suit number
                           1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,     //1 = clubs, 2 = spades, 3 = hearts, 4 = diamonds
                           1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4,
                           1,2,3,4,1,2,3,4,1,2,3,4};
        
        int[] _cardDeck = GenerateDeck();  //generates an initial deck
        String[] CONVERTED_cardDeck = ConvertDeck(_cardDeck);  //creates a deck where cards are named
       
        System.out.println("*****ORIGINAL DECK*****");
        for (int j=1; j<_cardDeck.length; j++) {System.out.println(j + ". " + CONVERTED_cardDeck[j]);}  //print the original deck
        
        int[] playerHand = DrawHand(_cardDeck);  //draws a hand for the player
        _cardDeck = DrawHandDeckChange(_cardDeck);  //changes deck by taking out player hand
        CONVERTED_cardDeck = ConvertDeck(_cardDeck);  //updates named deck to print
        
        System.out.println("*****FIRST NEW DECK*****"); 
        for (int j=1; j<_cardDeck.length; j++) {System.out.println(j + ". " + CONVERTED_cardDeck[j]);}  //prints named deck
        
        int[] compHand = DrawHand(_cardDeck);  //draws a hand for the computer
        _cardDeck = DrawHandDeckChange(_cardDeck);  //changes deck by taking out computer hand
        CONVERTED_cardDeck = ConvertDeck(_cardDeck);  //updates named deck to print
        
        System.out.println("*****SECOND NEW DECK*****");
        for (int j=1; j<_cardDeck.length; j++) {System.out.println(j + ". " + CONVERTED_cardDeck[j]);}  //prints named deck
        
        String[] CONVERTED_playerHand = ConvertDeck(playerHand);  //creates a named player hand
        String[] CONVERTED_compHand = ConvertDeck(compHand);  //creates a named computer hand
        
        System.out.println("*****PLAYER HAND*****");        
        for (int j=1; j<playerHand.length; j++) {System.out.println(j + ". " + CONVERTED_playerHand[j]);}  //prints player hand
        DisplayHand(playerHand, jButton1, jButton2, jButton3, jButton4, jButton5, jButton6, jButton7, jButton8);  //sets button icons of player hand
       
        System.out.println("*****COMPUTER HAND*****");        
        for (int j=1; j<compHand.length; j++) {System.out.println(j + ". " + CONVERTED_compHand[j]);} //prints computer hand
        
        jButton10.setIcon(new javax.swing.ImageIcon("C:\\Documents and Settings\\James Kovacs\\JavaGin\\" + DrawCardDeck(_cardDeck) + "_big.gif"));  //sets button icon for discard pile with top card from deck
        
        int[] _discardPile = new int[2]; //creats discard pile array
        _discardPile[1] = DrawCardDeck(_cardDeck);  //adds top card from deck to discard pile
        _cardDeck = DrawCardDeckChange(_cardDeck);  //updates deck by taking top card        
        CONVERTED_cardDeck = ConvertDeck(_cardDeck);  //updates nameds deck
        
        System.out.println("*****DRAWN FROM DECK*****");
        for (int j=1; j<_cardDeck.length; j++) {System.out.println(j + ". " + CONVERTED_cardDeck[j]);} //prints drawfrom deck
        
        jButton10.addActionListener(new ActionListener( ) {
            public void actionPerformed(ActionEvent ev) {
                playerHand = DrawCardHandChange(playerHand, DrawCardDiscard(_discardPile));  //should add card from discard to hand
                _discardPile = DrawCardDiscardChange(_discardPile);  //take top card from discard
            }
        });

    }
Advertisement
The problem is that you are accessing _discardPile, which is local to the constructor method App() of the class App, from within the actionPerformed method of a subclass of ActionListener.

Inside of the ActionListener, the variable _discardPile doesn't exist.

As for the "must be declared final" part, I don't recall exactly what it means, but I remember that there was some really odd quirk where you can declare something final (the variable or the class or something) and it would suddenly be visible within inner classes... like your ActionListener. I always thought it appeared to be an unwise thing to do, so I never bothered remembering the details... it sounds a bit "hackish".
I know it says declare those variables "final", but I have a feeling that won't help your problem. Try making those variables private members of your App class and see what happens.

Obviously, Java doesn't like local variables of one class being accessed by an inner class.

Beginner in Game Development?  Read here. And read here.

 

Quote:Original post by smitty1276
The problem is that you are accessing _discardPile, which is local to the constructor method App() of the class App, from within the actionPerformed method of a subclass of ActionListener.

Inside of the ActionListener, the variable _discardPile doesn't exist.


I like this answer. It makes sense [smile]


@Smitty: I thought however that because it an inner class of the main class that it was part of the main class just as a method would be, so therefore it could access local variables.... oh. you know what? answered my own question. [smile]

Beginner in Game Development?  Read here. And read here.

 

Go to this page, and scroll down to the section "Variable Visibility In Anonymous Classes", which discusses exactly this problem.

From the page...
Quote:The goofy, anonymous inner classes defined in the middle of a method, in addition to the other communication possibilities, have limited access to the local variables in the method from which it was spawned. I don't mean that local variables passed to the anonymous constructor are restricted. You can pass any value at all, both final and non-final, local or non-local to the anonymous class constructor.

The local variables that must be final in order to be accessed, live in the method that instantiates and encloses the anonymous class. The access we are talking about is direct use of the variable names from inside the methods of the anonymous class.

Again, let me explain by example...
It makes sense that they must be final, because their value would need to be known at compile time. Right?

This topic is closed to new replies.

Advertisement