Registrierung von Observer

lal000r

Mitglied
Hallo zusammen,


ich habe derzeit ein kleines Problem mit der Umsetzung des Observer-Patters. Zur Zeit programmiere ich ein Schachspiel mit GUI, in welchem ich versuche das MVC-Prinzip umzusetzen.

Ein menschlicher Spieler nimmt beispielsweise Spielzüge auf der GUI des Spiels vor und Listener fungieren dabei als Controller, um die Veränderungen am model durchzuführen.
Außerdem soll es aber auch möglich sein, dass der Computer Züge durchführt, also ein Mensch gegen den Computer spielt.
Für diesen Fall hab ich mir das so gedacht, dass das Model Observable ist und die View einen Observer implementiert. Soll heißen, wenn der Computer eine Änderung am Model macht, indem er einen Spielzug durchführt, soll die View das mitbekommen und einen repaint() machen.

Ganz grob klappt das auch, allerdings mit einer Notlösung. Ich weiß nicht recht, an welcher Stelle bzw. zu welcher Zeit ich den Observer registrieren muss.

Model:
Java:
package model;
import java.util.Observable;
import controller.BoardObserver;

public class Board extends Observable {

//Variablen
//Konstruktor
//Methoden

public void executeMove(Move move) {
// führt Änderungen am Model duch, Spielzug wird ausgeführt
setChanged();
IO.println(hasChanged());
notifyObservers();

Controller:
Java:
package controller;

import model.Board;
import model.Game;
import view.BoardGraphic;

public class BoardObserver {
Game currentgame;
public BoardObserver(BoardGraphic panel) {
//Holt das aktuelle Spiel, welches durch ein Singleton-Pattern instanziiert wird	
Game currentgame = GameManager.getInstance().getCurrentGame();
		
Board model = currentgame.getBoard();
model.addObserver(panel);
//Testausgabe zur Prüfung
IO.println("neuerObserver");
	}
}

View:
Java:
package view;
import model.Board;
import model.Game;
import controller.BoardObserver;
import controller.GameManager;
import controller.Mouselistener;
import controller.MousemotionListener;
etc....

public class BoardGraphic extends JPanel implements Observer {

	private static final long serialVersionUID = 1L;
	ActivePiece activepiece = null;
	boolean isDragging, isPressed, moveExecuted = false;
	final int CELLSIZE = 80;

	public BoardGraphic() {
		this.setPreferredSize(new Dimension(650, 600));
		this.setBackground(new Color(230, 230, 250));
		this.addMouseListener(new Mouselistener(this));
		this.addMouseMotionListener(new MousemotionListener(this));
//Erzeugen des Controllers		
BoardObserver controller = new BoardObserver(this);
	}
	

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		int xStart = this.getWidth() / 2;
		int yStart = this.getHeight() / 2;
		this.setFont(g);
..........usw.

	@Override
	public void update(Observable o, Object arg) {
		IO.println("update");
		this.repaint();
	}
}

Wenn ich also nun im Konstruktor der BoardGraphic (view) den Controller erzeugen möchte und das Panel selbst übergebe, kommt es zur StackOverflow Exception. Das liegt wohl daran, dass das Game, welches mit getCurrentGame() geholt wird, zu der Zeit noch nicht besteht. (Vermute ich).

Wenn ich den Observer erst weiter unten in der paintComponent()-Methode registriere klappt das Ganze. Aber sinnvoll erscheint mir das nicht.

GameManager:
Java:
public class GameManager {


	private static GameManager gameManager = null;
	private Game currentGame;

	protected GameManager() {
		currentGame = newHumanGame();
	}

	public static GameManager getInstance() {
		if (gameManager == null) {
			gameManager = new GameManager();
		}
		return gameManager;
	}
	
	public Game getCurrentGame() {
		return currentGame;
	}

	public Game newHumanGame() {
		Player humanA = new HumanPlayer(true);
		Player humanB = new HumanPlayer(false);
		
		currentGame = new Game(humanA, humanB);
		return currentGame;
	}

	public Game newGame(Player playerA, Player playerB) {
		currentGame = new Game(playerA, playerB);
		return currentGame;
	}
// Start des Spiels
	public static void main(String[] args) {
		GameManager.getInstance();


	}
}

Game (grob):
Java:
public class Game {
	
		private Board board;
		private Referee referee;
		private GUI gui;
		private Player[] player;
		private Player currentPlayer;
		private boolean end;
		
		public Game(Player playerA, Player playerB) {
			this.board = new Board();
			this.referee = new Referee();
			this.player = new Player[2];
			this.player[0] = playerA;
			this.player[1] = playerB;
			this.currentPlayer = playerA;
			this.gui = new GUI("Spiel");
			this.end = false;
		}

Vielleicht steigt ja jemand durch meinen Code und kann mir einen Tipp geben ;) Vielen Dank schonmal!
 
Zuletzt bearbeitet:
S

SlaterB

Gast
GameManager erzeugt ein Game, das Game erstellt eine neue GUI, die GUI braucht GameManager, welcher noch nicht initialisiert ist,
also zweiter GameManager usw.,
hättest du den StackTrace gepostet oder selber angeschaut wäre das bestimmt deutlicher zu erkennen als nur am Code

ein klassisches Problem, Lösungen auch mehr oder weniger offensichtlich, die Initialisierungsprozesse müssen auseinander gezogen werden,
der GameManager-Konstruktor und der Game-Konstruktor könnten leer sein oder zumindest auf die kompliziertesten Dinge verzichten,
bei GameManager ist es bisher nur das Game, also alles zu streichen, im Game könnte aber allein die GUI wegfallen, die ist dort bestenfalls sowieso gar nicht benötigt

dazu dann eine zentrale Stelle die alles initialisiert,
einen GameManager erzeug, ein Game, eine GUI usw.,
das Game beim GameManager einfügt, die GUI beim Game usw.

für den Moment würde es reichen nur eine Stelle aufzubrechen, GameMangager könnte ruhig wie bisher das Game erzeugen,
nur die GUI aus Game am Anfang raus, das müsste den Teufelskreis auch schon lösen
 

lal000r

Mitglied
Danke für deine schnelle Antwort.
Ich glaube, das ist genau mein Problem. Dies ist das erstere größere Programm, welches ich in OOP schreibe. Die Fäden müssen ja alle irgendwo wieder zusammenlaufen und da hakts bei mir noch ein bisschen.
Ich wüsste jetzt nicht, wo ich die GUI erzeugen soll, wenn sie nicht im Game erzeugt wird. Hatte mir so vorgestellt, dass ich da alles zusammenbringe. Wenn du sagst, dass der GameManager bzw. das Game leer sein könnten, kann ich dir nicht ganz folgen. Irgendwo muss ich doch alles erzeugen?
Wenn ich das alles in Methoden auslagere und diese dann im Konstruktor nutze, macht das ja keinen großen Unterschied.
Oder meinst du, dass ich die Komponenten dann in der main erzeugen sollte? (Zur Info: Ich versuche nebenbei auch noch gerade den sinnvollen Einsatz von Threads zu implementieren.)

Hier mal ein kleiner Auszug des StackTrace: (Das ganze Ding würde über mehrere Seiten gehen)
Java:
Exception in thread "main" java.lang.StackOverflowError
	at sun.awt.Win32GraphicsConfig.getBounds(Native Method)
	at sun.awt.Win32GraphicsConfig.getBounds(Unknown Source)
	at java.awt.Window.init(Unknown Source)
	at java.awt.Window.<init>(Unknown Source)
	at java.awt.Frame.<init>(Unknown Source)
	at java.awt.Frame.<init>(Unknown Source)
	at javax.swing.JFrame.<init>(Unknown Source)
	at view.GUI.<init>(GUI.java:16)
	at model.Game.<init>(Game.java:27)
	at controller.GameManager.newHumanGame(GameManager.java:35)
	at controller.GameManager.<init>(GameManager.java:17)
	at controller.GameManager.getInstance(GameManager.java:22)
	at controller.BoardObserver.<init>(BoardObserver.java:13)
	at view.BoardGraphic.<init>(BoardGraphic.java:43)
	at view.MainPanel.addBoardGraphic(MainPanel.java:46)
	at view.MainPanel.<init>(MainPanel.java:24)
	at view.GUI.<init>(GUI.java:12)
	at model.Game.<init>(Game.java:27)
...............
 
S

SlaterB

Gast
nimm die main-Methode, schaffe in einem Controller eine entsprechende 'initialisiere alles'-Methode oder wo auch immer,
das sollte ja nun nicht das Problen sein,

------

einen Controller, der genau kein Observer ist, BoardObserver zu nennen, ist übrigens keine Idee, was spricht etwa gegen BoardController?
 

lal000r

Mitglied
Eigentlich ist er ja ein Oberver, bzw. registriert ihn, oder nicht?

Hmm, dann muss ich mir sowieso nochmal grundsätzlich Gedanken machen, wo es klug wäre, alles zu erzeugen, bzw. die Threads zu starten.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
X Registrierung eines Ecore-Models außerhalb der Eclipse-Umgebung Allgemeine Java-Themen 0
G Button-Registrierung beim ActionListener erst NACH Tastendruck Allgemeine Java-Themen 2
A RMI class not found bei Registrierung Allgemeine Java-Themen 4
M OOP Design Pattern - "extends Observable implements Observer" Allgemeine Java-Themen 0
GreenTeaYT Verstehe nicht ganz das Observer Pattern in einer Arrayliste? Allgemeine Java-Themen 3
S OOP JFrame als Observer eines JPanel Allgemeine Java-Themen 3
A Observer und Initialisierung Allgemeine Java-Themen 7
G 2 Observable und ein Observer... Allgemeine Java-Themen 4
M MVC: PropertyChangeListener vs Java Observer & Observable Allgemeine Java-Themen 11
S Wie kann ein Observer mehrere Observables beobachten? Allgemeine Java-Themen 9
Z Observer/Observable & Grundlagen Allgemeine Java-Themen 6
R Observer Umsetzungsproblem Allgemeine Java-Themen 7
K Verständnisprobleme bei Observer-Pattern mit größerem Datenmodell Allgemeine Java-Themen 32
nrg Java Observer in SysTray laufen lassen / Console schließen Allgemeine Java-Themen 2
T Observer vs Listener Allgemeine Java-Themen 18
A Observer Pattern: feuern bei neuer Referenz-Zuweisung? Allgemeine Java-Themen 8
V Threads und Observer Allgemeine Java-Themen 18
H Observer und Observable Allgemeine Java-Themen 3
U Verständnisschwierigkeiten Observer Pattern Allgemeine Java-Themen 18
B Observer vs Listener (GUI-Programmierung) Allgemeine Java-Themen 5
M Observer serialisieren Allgemeine Java-Themen 7
G Observer / Observable oder doch lieber Message Broker? Allgemeine Java-Themen 2
D Observer/Observable Pattern vs. Listener-Konzept Allgemeine Java-Themen 4
P Observer/TimerTask Allgemeine Java-Themen 3
P Observer Allgemeine Java-Themen 4
N Observer/Observable der JAVA-API od. eigene Implementierung Allgemeine Java-Themen 2
B Observer reagieren beim 2ten mal nicht Allgemeine Java-Themen 23
P Observer, nicht alle updates bearbeiten Allgemeine Java-Themen 2
P Abmelden beim Observer Allgemeine Java-Themen 4
N Observer Pattern Allgemeine Java-Themen 2
M Frage zu update Methode von Observer! Allgemeine Java-Themen 40
lhein Tutorial zu Observer / Observable? Allgemeine Java-Themen 6
G problem mit dem observer pattern Allgemeine Java-Themen 3
S Observable und Observer Allgemeine Java-Themen 10
G Frage zu (mehrfachem) Observable/Observer Allgemeine Java-Themen 2
G Frage zum Observer Pattern Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben