Frage zu ActionListenern

Chasor

Aktives Mitglied
Ich habe für ein Spiel 2 Menübuttons mit jeweils einem ActionListener.

Solve-Listener:
Java:
// Solve-Listener
    mSave.addActionListener(new ActionListener()
    {
    	public void actionPerformed(ActionEvent e)
    	{
    		while(validrows==false||validcols==false)
    		{
        		for(int m = 0; m < field.nbCols; m++)
        		{
        			for(int n = 0; n < field.nbRows; n++)
        			{
        				for(int o = 0; o < 3; o++)
        				{
        					field.array[m][n] = o;
        					//Control-Listener starten
        					//Wenn validrows und validcols == true werden, abbrechen und die Werte merken
        				}
        			}
        		}
    		}
    	}
    });

Control-Listener:
Java:
// Control-Listener
    mControl.addActionListener(new ActionListener()
    {    
    	// Result-Control
    	public void actionPerformed(ActionEvent e)
    	{
    	[...]
    	}
    });


Ich möchte also die Schritte, die innerhalb von "Result-Control" liegen, im Solve-Listener durchgehen, die Werte speichern, bei denen die boolean Variablen true sind, und mit diesen Werten weiterarbeiten.
Ich habe bereits versucht, den Result-Control in eine externe Methode "public void control()" zu verlagern, diese Methode kann ich dann aber innerhalb der actionPerformed-Methoden nicht mehr aufrufen (NullPointerException).

Gibt es einen Weg, wie ich das vernünftig hin bekommen kann?
Und wie sage ich dem Solve-Listener, dass er bei valid-Werten aufhören soll, die Schleifen durchzugehen? Die While-Schleife muss ja wenn valid-Werte durchgegeben werden automatisch abgebrochen werden.
 
Ich blicke zwar nicht, was das ganze am ende tun soll, aber Schleifen abbrechen kannst du mit "break;" und "validrows" und "validcols" kannst du auch innerhalb der for-Schleife stets mir "if" überprüfen und gegebenenfalls den Schleifendurchlauf mit "break" abbrechen. Wenn du bestimmte Werte im Laufe der Schleifendurchgäng sammeln willst, lege doch vor der ersten Schleife ein Array oder, wenn du nicht abschätzen kannst, wie viele Werte es werden, eine ArrayList an, zu der du jeden relevanten Wert hinzufügst.
Am Ende aller Schleifendurchläufe hast du dann eine Liste mit allen interessanten Werten, mit der du weiterarbeiten kannst.

Außerdem ist es definitiv möglich, aus "actionPerformed" eine weitere Methode des Listeners aufzurufen. Und warum bekommst du eine NullPointerException?! Die gibt's immer dann, wenn du auf ein Objekt zugreifen willst, das also "null" ist. Welches Objekt ist das also, auf das du zuzugreifen versuchst, ohne dass es exisitert?
 
Java:
public Gui()
{ 
    // Control-Listener
    mControl.addActionListener(new ActionListener()
    {    
    	// Result-Control
    	public void actionPerformed(ActionEvent e)
    	{
    		control();
    	}	
   	});
    
}


Java:
public void control()
{	
[...]
}


Ich bekomme hier eine NullPointerException.

"Gui.control" kann ich nicht machen, dann muss ich die Methode als static deklarieren, dann kommen hunderte Fehler in meiner control()-Methode :/, da ich sonst kaum Variablen als static deklariert habe ...

/Edit:
Hab's gerade mal testweise als static deklariert und alle nötigen Variablen auch.
Bekomme immernoch eine Nullpointerexception.
 
Zuletzt bearbeitet:
Also du bekommst innerhalb der control()-Methode die NPE? Falls ja, dann poste mal den Code der control()-Methode.

NullPointerException (kurz NPE) heisst, dass ein Objekt nicht mit new erzeugt worden ist. Wenn du über das nicht mit new instanzierte Objekt auf irgendwas zugreiffen möchtest bekommst du eine NEP.

Aus dem geposteten Code ist für mich allerdings nicht ersichtlich wiso die NEP ausgelöst wird.

Noch so als Tipp:
Methoden und Variablen static zu machen ist oft die falsche Lösung. Nur Dinge als static deklarieren, wenn es wirklich Sinn macht.
 
Direkt in der ersten Zeile schlägt die NPE an.
"final Field field = new Field();" wurde im Konstruktor vorgenommen.

Java:
marray = new char[field.nbCols];
    		validrows = true;
    		validcols = true;
    		
    		/* Felder werden durchgegangen und die Inhalte der Zeilen
    		   mit den Zeileninformationen aus der Datei verglichen. */
    		for (int i = 0; i < field.nbRows;i++)
    		{
    			// Schwarze Felder in einer Reihe
    			rowfs = new int[field.nbRows];
    			// Bloecke in einer Reihe
    			rowbs = new int[field.nbRows];
    			// Gesicherte (sicher nicht ausgefüllte) Felder in einer Reihe
    			rowsafe = new int[field.nbRows];
    			validrow = new boolean[field.nbRows];
    			if(array[0][i]==1)
    				rowbs[i] = rowbs[i] + 1;
    			// Bei n = 1 anfangen, da array[-1][i] nicht zu erreichen waere
    			for(int n = 1; n<field.nbCols; n++)
    			{
    				// Zählt die Blockzahl der Reihen durch
    				if(array[n][i]==1 && array[n-1][i]!=1)
    				{
    					rowbs[i] = rowbs[i] + 1;
    				}
    			}
    			for(int n = 0; n<field.nbCols; n++)
    			{
    				marray[n] = (char) array[n][i];
    				// Zählt die Anzahl der eingefärbten Felder
    				if(array[n][i] == 1)
    				{
    					rowfs[i] = rowfs[i]+array[n][i];
    				}
    				// Zählt die Anzahl der sicheren Felder
    				if(array[n][i] == 2)
    				{
    					rowsafe[i] = rowsafe[i]+1;
    				}
    			}
    			//System.out.println("Zeile "+(i+1)+" hat "+rowfs[i]+" schwarze Felder, "+rowbs[i]+" Bloecke und "+rowsafe[i]+" "+(field.nbCols-rowfs[i])+" freie Felder.");
    			
    			// Ergebnisse der Zählungen werden mit den Informationen aus der Datei verglichen
    			// (für Zeilen)
    			if(rowfs[i] == rowfields[i] && rowbs[i] == rowblocks[i] && rowsafe[i] == field.nbCols - rowfs[i])
    			{
    				validrow[i] = true;
    			}
    			else
    			{
    				validrow[i] = false;
    			}
    			//System.out.println(validrow[i]);
    			if(!validrow[i])
    			{
    				validrows = false;
    				break;
    			}
    		}
    		
    		/* Felder werden durchgegangen und die Inhalte der Spalten
    		   mit den Spalteninformationen aus der Datei verglichen.
    		   (selber Vorgang wie oben bei Row-Control) */
    		for (int n = 0; n < field.nbCols;n++)
    		{
    			colfs = new int[field.nbCols];
    			colbs = new int[field.nbCols];
    			colsafe = new int[field.nbCols];
    			validcol = new boolean[field.nbCols];
    			if(array[n][0]==1)
    				colbs[n] = colbs[n] + 1;
    			for(int i = 1; i<field.nbRows; i++)
    			{
    				if(array[n][i]==1 && array[n][i-1]!=1)
    				{
    					colbs[n] = colbs[n] + 1;
    				}
    			}
    			for(int i = 0; i<field.nbRows; i++)
    			{
    				marray[n] = (char) array[n][i];
    				if(array[n][i] == 1)
    				{
    					colfs[n] = colfs[n]+array[n][i];
    				}
    				if(array[n][i] == 2)
    				{
    					colsafe[n] = colsafe[n]+1;
    				}
    			}
    			//System.out.println("Spalte "+(n+1)+" hat "+colfs[n]+" schwarze Felder, "+colbs[n]+" Bloecke und "+colsafe[n]+" "+(field.nbRows-colfs[n])+" freie Felder.");
    			
    			// Ergebnisse der Zählungen werden mit den Informationen aus der Datei verglichen
    			// (für Spalten)
    			if(colfs[n] == colfields[n] && colbs[n] == colblocks[n] && colsafe[n] == field.nbRows - colfs[n])
    			{
    				validcol[n] = true;
    			}
    			else
    			{
    				validcol[n] = false;
    			}
    			//System.out.println(validcol[n]);
    			if(!validcol[n])
    			{
    				validcols = false;
    				break;
    			}
    		}
    		//System.out.println(validrows+" "+validcols);
    		
    		// Sind Zeilen- und Spaltenwerte richtig, kommt eine Meldung zum Erfolg
    			if(validrows==true&&validcols==true)
    			{
    				JOptionPane.showMessageDialog(Gui.this, "Glückwunsch! Dein Ergebnis ist korrekt!", "RICHTIG!",JOptionPane.INFORMATION_MESSAGE);
    			}
    			// Sind Zeilen- und Spaltenwerte falsch, kommt eine Meldung zum Misserfolg
    			if(validrows==false||validcols==false)
    			{
    				JOptionPane.showMessageDialog(Gui.this, "Leider falsch! Versuche es weiter.", "FALSCH!",JOptionPane.INFORMATION_MESSAGE);
    			}


Ich glaube es liegt vllt. am "final Field field ...". Wenn ich das final wegmache, tauchen jedoch im restlichen Code hunderte Fehler auf:
"Cannot refer to a non-final variable field inside an inner class defined in a different method"

Werde da nicht schlau draus.

Die ActionListener definiere ich immer in eigenen Klassen:
Java:
mControl.addActionListener(new ActionListener()
    {    
    	// Result-Control
    	public void actionPerformed(ActionEvent e)
    	{
[...]

Könnte daran liegen, richtig?



/Edit: Konnte das final entfernen, musste in jeden ActionListener nur ein "Field field;" integrieren.
Dann waren diese Fehler schonmal beseitigt. Der Aufruf von control() geht immernoch nicht :/. Er meckert immernoch wegen nicht-static Variablen überall rum :/
 
Zuletzt bearbeitet:
Kann es sein, dass du noch das als Membervariable hast?
[Java]
Field field;
[/Java]

Falls ja, dann hast du das Problem, dass du das Objekt field in deinem Konstruktor "überschreibst". Falls es so ist, dann schreibe mal im Konstruktor nur das hier:
[Java]
field = new Field();
[/Java]

Da es vielleicht etwas merkwürdig klingt habe ich hier kurz zwei Klassen geschrieben, die dir das Problem hoffentlich zeigen können.


In dieser Klasse wird eine NPE ausgelöst. Wiso siehst du im Kommentar
[Java]
public class WrongVersion {

Field field; // Objekt field als Membervariable

public WrongVersion(){

// das Objekt field wird im Konstruktor neu definiert.
// deswegen hat die Instanzierung mit new keine Auswirkung auf das obere field,
// das als Membervariable deklariert ist
Field field = new Field();


}

public void test(){
field.methodenName(); // löst eine NPE aus, da field als Membervariable nicht mit new erzeugt wurde
}

}
[/Java]

Diese Klasse hingegen löst keine NPE aus
[Java]
public class CorrectVersion {

Field field;

public CorrectVersion(){

field = new Field(); // field wird korrekt mit new erzeugt

}

public void test(){

field.methodenName(); // löst keine NPE aus

}

}
[/Java]

PS:
Ich bin nicht sicher, ob das Problem bei dir zutrifft.
 
Zuletzt bearbeitet:
Hm, mal kurz testen ^^...

/Edit:
Funktioniert immernoch nicht.

Java:
    // Control-Listener
    mControl.addActionListener(new ActionListener()
    {    
    	Gui gui;
    	// Result-Control
    	public void actionPerformed(ActionEvent e)
    	{
    		gui.control(); //<- hier Exception
    	}	
   	});
"Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException"
 
Zuletzt bearbeitet:
Gui gui = new Gui();

Ich weiss allerdings nicht ob es clever ist da die gui zu instanzieren. Dazu kenne ich zu wenig Code. Sollte aber Problem mit der NPE beheben.
 
Zuletzt bearbeitet:

Zurück
Oben