Klassen Minesweeper Problem. int needs to be final (inner class problem)

Coold0wn

Mitglied
Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;


public class Minesweeper extends JFrame
{
    private JFrame MainFrame = new JFrame("Minesweeper");
    private JButton[][] feld;
    private boolean[][] bomben;
    Random rand = new Random();
    public Minesweeper(int breite, int hoehe, int schwierigkeitsgrad)
    {
        MainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        MainFrame.getContentPane().setLayout(null);   
        feld = new JButton[breite][hoehe];
        bomben = new boolean[breite][hoehe];
        for(int i = 0; i < hoehe; i++)
        {
            for(int j = 0; j < breite; j++)
            {
                feld[j][i] = new JButton();
                MainFrame.getContentPane().add(feld[j][i]); 
                feld[j][i].setBounds(16*j + MainFrame.getInsets().left, 16*i + MainFrame.getInsets().top, 16, 16);
                int k = rand.nextInt(10);
                if(k == 1)
                    bomben[j][i] = true;
                else
                    bomben[j][i] = false;
                feld[j][i].setMnemonic(KeyEvent.VK_I);
                feld[j][i].addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) 
                {
                    if(bomben[j][i])
                    {
                        feld[j][i].setText("X");
                        feld[j][i].setForegroundColor(Color.blue);
                    }
                    else
                    {
                        int l = 0;
                        if(bomben[j++][i])
                        l++;
                        if(bomben[j][i++])
                        l++;
                        if(bomben[j--][i])
                        l++;
                        if(bomben[j][i--])
                        l++;
                        if(bomben[j++][i++])
                        l++;
                        if(bomben[j--][i--])
                        l++;
                        if(bomben[j++][i--])
                        l++;
                        if(bomben[j--][i++])
                        l++;
                        feld[j][i].setText(""+l);
                    }
                }
            });
            }
        }
        MainFrame.getContentPane().setBackground(Color.BLUE);
        MainFrame.setSize((breite)*16+16, (hoehe+1)*16+22);
        MainFrame.setVisible(true);
        //MainFrame.setResizable(false);
    }
}


ERROR: local variable j (and i) is accessed from within inner class; needs to be declared final.



I have not a single clue how to fix this.. googling didnt help me. i did it once like this but without that for-loop. Any help appreciated!
(this is going to be a minesweeper-game by the way. a 2D array with buttons and one with a boolean that says if it is a bomb or not)

if you have any questions , feel free to ask.


edit: ah das is ja ein deutsches forum 😀 (bin neu hier), also Antworten auch gerne auf deutsch.
 
Zuletzt bearbeitet:
You try to add an ActionListener to a Swing Component within a for-Loop.

Inside of this ActionListener you are using the Variables i, j. Closure are not supported by Java (yet)

You have to pass this variables to the action Lisener by its Constructor Parameters. Therefore you have to implement a new Class for your Actionlistener indead of using an Inner class.

---

Habe ich mir fast gedacht 😉 bei deutschen Variablennamen.
 
You try to add an ActionListener to a Swing Component within a for-Loop.

Inside of this ActionListener you are using the Variables i, j. Closure are not supported by Java (yet)

You have to pass this variables to the action Lisener by its Constructor Parameters. Therefore you have to implement a new Class for your Actionlistener indead of using an Inner class.

---

Habe ich mir fast gedacht 😉 bei deutschen Variablennamen.

puh ich hab davon keine ahnung 😀 hier mein versuch:

Klasse 1:

Code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;


public class Minesweeper extends JFrame
{
    private JFrame MainFrame = new JFrame("Minesweeper");
    private Button[][] feld;
    Random rand = new Random();
    public Minesweeper(int breite, int hoehe, int schwierigkeitsgrad)
    {
        MainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        MainFrame.getContentPane().setLayout(null);   
        feld = new Button[breite][hoehe];
        for(int i = 0; i < hoehe; i++)
        {
            for(int j = 0; j < breite; j++)
            {
                feld[j][i] = new Button(j, i, MainFrame, this);
                int k = rand.nextInt(10);
                if(k == 1)
                    feld[j][i].setBombeTrue();
            }
        }
        MainFrame.getContentPane().setBackground(Color.BLUE);
        MainFrame.setSize((breite)*16+16, (hoehe+1)*16+22);
        MainFrame.setVisible(true);
        //MainFrame.setResizable(false);
    }
    
    public int countBombs(int j, int i)
    {
        int l = 0;
        if(feld[j++][i].gibBombe())
            l++;
        if(feld[j][i++].gibBombe())
            l++;
        if(feld[j--][i].gibBombe())
            l++;
        if(feld[j][i--].gibBombe())
            l++;
        if(feld[j++][i++].gibBombe())
            l++;
        if(feld[j--][i--].gibBombe())
            l++;
        if(feld[j++][i--].gibBombe())
             l++;
        if(feld[j--][i++].gibBombe())
            l++;
            
        return l;
    }
}

Klasse2:

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

public class Button
{
    private JButton button;
    private boolean bombe = false;
    public Button(int x, int y, JFrame MainFrame, Minesweeper m)
    {
        final int j = x;
        final int i = y;
        final Minesweeper minesweeper = m;
        button = new JButton();
        MainFrame.getContentPane().add(button); 
        button.setBounds(16*x + MainFrame.getInsets().left, 16*y + MainFrame.getInsets().top, 16, 16);
        
                button.setMnemonic(KeyEvent.VK_I);
                button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) 
                {
                    if(bombe)
                    {
                        button.setText("X");
                    }
                    else
                    {
                        button.setText("" + minesweeper.countBombs(i, j));
                    }
                }
            });
    }
    
    public void setBombeTrue()
    {
        bombe = true;
    }
    
    public boolean gibBombe()
    {
        return bombe;
    }
}


jetz sagt er m in Button is nicht final und deswegen funktioniert es nicht... ;(


edit: hab die klassen aktualisiert.

ES KLAPPT!
DANKE! 🙂

edit2: das mit den zahlen klappt gar nich gut.....^^ der weiß nich wo bomen sind und wo nicht..
 
Zuletzt bearbeitet:
hi Leute ich bins nochmal.
Ich hab wieder ein Problem. Bin jetzt komplett fertig mit dem Spiel (timer, restart button und den ganzen spaß mit reingebracht), aber es is langsam. und zwar, wenn man bei minesweeper auf ein Feld mit 0 bomben geht, dann werden alle felder mit 0 und die umliegenden felder auch noch sichtbar. Und dieser Prozess dauert zu lang. Das können bis zu 5 Sekunden sein....
Hier mal der code von entsprechender Stelle:

Code:
public void clickOthers(int i, int j)
    {
        stopped = true;
        if(i < b-1)
        {
            feld[i+1][j].doClick();
        }
        if(i > 0)
        {
            feld[i-1][j].doClick();
        }
        if(j < h-1)
        {
            feld[i][j+1].doClick();
        }
        if(j > 0)
        {
            feld[i][j-1].doClick();
        }
        if((i < b-1) && (j < h-1))
        {
            feld[i+1][j+1].doClick();
        }
        if((i > 0) && (j > 0))
        {
            feld[i-1][j-1].doClick();
        }
        if((i < b-1) && (j > 0))
        {
            feld[i+1][j-1].doClick();
        }
        if((i > 0) && (j < h-1))
        {
            feld[i-1][j+1].doClick();
        }
        stopped = false;
    }

die if abfragen gucken ob der JButton am rand liegt, weil dann wär der Platz im 2D array wenn man was abzieht/dazurechnet ja null und das darf nicht.
Wenn jemand den ganzen code will, einfach sagen. Kann ja nicht sein das Minecraft so gut wie flüssig läuft und der hier ewig braucht 😛
Bitte Hilfe! danke
 

Zurück
Oben