2D-Grafik Vier gewinnt Problem

Vancold

Aktives Mitglied
Hallo liebe Community!

Ich habe folgendes Problem: Zurzeit programmiere ich an meinem Vier gewinnt.
Die meisten Probleme konnte ich selbst lösen, aber zurzeit stehe ich gerade an bei einem Problem.
Es geht um Threads. Ich habe in meinem Programm einen Thread für die Animation zum Einwerfen.
Wenn ich diesen Thread im Synchronized block ausführe also mit start() führt er den Inhalt der run Methode nicht aus. Mache ich das ganze ohne Synchronized kann ich nicht gewährleisten das das Programm richtig läuft, da ich keine Möglichkeit habe es zu schaffen einen Einwurf nach dem anderen zu machen.

Java Code steht am Ende des beitrags

Probiert es mal ohne Synchronized Block und ihr werdet sehen was ich meine. Dann arbeitet das programm nicht richtig. btw das ist keine Hausübung ich mache das freiwillig und zum Spaß 😉

Falls es Verbesserungsvorschläge gibt ich bin immer für welche offen 🙂
Bin ja nicht perfekt 😉

mfg,


Vancold

PS: JAVA code steht unterhalb ;P
Leider ist es nicht fertig Dokumentiert. Wenn ihr fragen habt bitte einfach fragen 😉

Java:
package vierGewinnt;

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

/**
 * VGPanelklasse
 * 
 * Diese Klasse beinhaltet die GUI-Componenten + der zugehörigen Listener.
 * Sie hat die Aufgabe das eigentliche Spiel + Funktionen des Spiels darzustellen.
 * 
 * @author  Rene Polak
 * @version 2010-11-17
 */
public class VGPanel extends JPanel {
	
	// Komponenten für die GUI
	private JPanel groupPanel1,groupPanel2,groupPanel3;
	private JButton reset;
	private JLabel spieleStatus;
	// Mouse & Buttonlistener
	private MouseHandler mh;
	private ButtonHandler bh;
	// Spielfelder (JPanels)
	private Feld[] einwurfsFelder;
	private Feld[][] felder;
	// Speichert welcher Spieler gerade am Zug ists
	private int spieler;

	// Thread welcher die Steine, die zum Gewinn geführt haben, blinken lässt
	private BlinkThread bt;
	private WurfAnimationsThread wat;
	// Schaltervariable (Siehe Zeile 92)
	private boolean schalter;

	/**
	 * Defaultkonstruktor
	 */
	public VGPanel() {
		
		// Layout des Obejkts setzten
		this.setLayout(new BorderLayout());
		
		this.schalter = false;
		this.spieler = 1; 
		
		// gruppierungsPanel mit GridLayout 6*7 initialisieren und Hintergrundfarbe setzen
		this.groupPanel1 = new JPanel(new GridLayout(6,7,5,5));
		this.groupPanel1.setBackground(Color.BLUE);
	
		// MouseListener intialisieren
		mh = new MouseHandler();
		// Das zwei Dimensionale feld Array initialisieren
		this.felder = new Feld[6][7];
		
		// Felder Intialisieren und dem groupPanel 1 hinzufügen
		for(int i = 0; i < this.felder.length; i++) {
			for(int j = 0; j < this.felder[i].length; j++) {
				
				this.felder[i][j] = new Feld(Feld.LEER,Color.BLUE);
				this.groupPanel1.add(this.felder[i][j]);
				
			}
		}
		
		// GroupPanel 2 mit GridLayout 1*6 initialisieren & Hintergrundfarbe setzen
		this.groupPanel2 = new JPanel(new GridLayout(1,6,5,5));
		this.groupPanel2.setBackground(Color.WHITE);
		// Felder Array intialisieren
		this.einwurfsFelder = new Feld[7];
	
		// 
		for(int i = 0; i < einwurfsFelder.length; i++ ) {
			this.einwurfsFelder[i] = new Feld(Feld.LEER,Color.WHITE);
			this.einwurfsFelder[i].addMouseListener(mh);
			this.groupPanel2.add(this.einwurfsFelder[i]);
		}
		
		this.bh = new ButtonHandler();
		this.reset = new JButton("Neustarten");
		this.reset.addActionListener(bh);
		this.reset.setPreferredSize(new Dimension(120,30));
		
		this.spieleStatus = new JLabel("Spieler 1");
		this.spieleStatus.setPreferredSize(new Dimension(150,30));
		this.groupPanel3 = new JPanel(new FlowLayout(FlowLayout.CENTER));
		
		this.groupPanel3.add(reset);
		this.groupPanel3.add(spieleStatus);
		
		this.groupPanel2.setPreferredSize(new Dimension(300,35));
		this.add(groupPanel2,BorderLayout.NORTH);
		this.add(groupPanel1, BorderLayout.CENTER);
		this.add(groupPanel3,BorderLayout.SOUTH);
		
	}
	
	private boolean gewonnen() {
		/*
		 * Diese Schalter ist dazu da um den Spieler abzuhalten Spielsteine nach dem Sieg zu setzen
		 * Da der Thread den Zustand kurzzeitig auf 0 setzt ist es wieder möglich Steine zu setzen.
		 * Darum wird ein Schalter aktiviert der die Unterbindet.
		 */
		if(schalter != true) {
		for(int i = 0; i < felder.length; i++) {
			for(int j = 0; j < 4; j++) {
				if((felder[i][j].getZustand()== 1)&&(felder[i][j+1].getZustand()== 1)&&(felder[i][j+2].getZustand()== 1)&&(felder[i][j+3].getZustand()== 1)) {
					Feld[] reihe = new Feld[4];
					reihe[0] = felder[i][j];
					reihe[1] = felder[i][j+1];
					reihe[2] = felder[i][j+2];
					reihe[3] = felder[i][j+3];
					bt = new BlinkThread(reihe,spieler);
					bt.start();
					schalter = true;
					return true;
				}
				if((felder[i][j].getZustand()== 2)&&(felder[i][j+1].getZustand()== 2)&&(felder[i][j+2].getZustand()== 2)&&(felder[i][j+3].getZustand()== 2)) {	
					Feld[] reihe = new Feld[4];
					reihe[0] = felder[i][j];
					reihe[1] = felder[i][j+1];
					reihe[2] = felder[i][j+2];
					reihe[3] = felder[i][j+3];
					bt = new BlinkThread(reihe,spieler);
					bt.start();
					schalter = true;
					return true;		
				}
			}
		}
		for(int i = 0; i < felder[0].length; i++) {
			for(int j = 0; j < 3; j++) {
				if((felder[j][i].getZustand()== 1)&&(felder[j+1][i].getZustand()== 1)&&(felder[j+2][i].getZustand()== 1)&&(felder[j+3][i].getZustand()== 1)) {
					Feld[] reihe = new Feld[4];
					reihe[0] = felder[j][i];
					reihe[1] = felder[j+1][i];
					reihe[2] = felder[j+2][i];
					reihe[3] = felder[j+3][i];
					bt = new BlinkThread(reihe,spieler);
					bt.start();
					schalter = true;
					return true;
				}
				if((felder[j][i].getZustand()== 2)&&(felder[j+1][i].getZustand()== 2)&&(felder[j+2][i].getZustand()== 2)&&(felder[j+3][i].getZustand()== 2)) {	
					Feld[] reihe = new Feld[4];
					reihe[0] = felder[j][i];
					reihe[1] = felder[j+1][i];
					reihe[2] = felder[j+2][i];
					reihe[3] = felder[j+3][i];
					bt = new BlinkThread(reihe,spieler);
					bt.start();
					schalter = true;
					return true;		
				}
			}
		}

		for(int i = 0; i < 4; i++) {
			for(int j = 0; j < 3; j++) {
				if((felder[j][i].getZustand()== 1)&&(felder[j+1][i+1].getZustand()== 1)&&(felder[j+2][i+2].getZustand()== 1)&&(felder[j+3][i+3].getZustand()== 1)) {
					Feld[] reihe = new Feld[4];
					reihe[0] = felder[j][i];
					reihe[1] = felder[j+1][i+1];
					reihe[2] = felder[j+2][i+2];
					reihe[3] = felder[j+3][i+3];
					bt = new BlinkThread(reihe,spieler);
					bt.start();
					schalter = true;
					return true;
				}
				if((felder[j][i].getZustand()== 2)&&(felder[j+1][i+1].getZustand()== 2)&&(felder[j+2][i+2].getZustand()== 2)&&(felder[j+3][i+3].getZustand()== 2)) {	
					Feld[] reihe = new Feld[4];
					reihe[0] = felder[j][i];
					reihe[1] = felder[j+1][i+1];
					reihe[2] = felder[j+2][i+2];
					reihe[3] = felder[j+3][i+3];
					bt = new BlinkThread(reihe,spieler);
					bt.start();
					schalter = true;
					return true;		
				}
			}	
		}
		for(int i = felder.length-1; i >= 3 ; i--) {
			for(int j = 0; j < 4; j++) {
				if((felder[i][j].getZustand()== 1)&&(felder[i-1][j+1].getZustand()== 1)&&(felder[i-2][j+2].getZustand()== 1)&&(felder[i-3][j+3].getZustand()== 1)) {
					Feld[] reihe = new Feld[4];
					reihe[0] = felder[i][j];
					reihe[1] = felder[i-1][j+1];
					reihe[2] = felder[i-2][j+2];
					reihe[3] = felder[i-3][j+3];
					bt = new BlinkThread(reihe,spieler);
					bt.start();
					schalter = true;
					return true;

				}
				if((felder[i][j].getZustand()== 2)&&(felder[i-1][j+1].getZustand()== 2)&&(felder[i-2][j+2].getZustand()== 2)&&(felder[i-3][j+3].getZustand()== 2)) {	
					Feld[] reihe = new Feld[4];
					reihe[0] = felder[i][j];
					reihe[1] = felder[i-1][j+1];
					reihe[2] = felder[i-2][j+2];
					reihe[3] = felder[i-3][j+3];
					bt = new BlinkThread(reihe,spieler);
					bt.start();
					schalter = true;
					return true;
							
				}
			}	
		}
		} else {
			return true;
		}
		return false;
		
	}
	
	public boolean unentschieden() {
		int anzahl = felder.length*felder[0].length;
		int zaehler = 0;
		
		for(int i = 0; i < felder.length; i++) {
			for(int j = 0; j < felder[i].length; j++) {
				if(felder[i][j].getZustand() == 1 ||felder[i][j].getZustand() == 2) {
					zaehler += 1;
				}
			}
		}
		if(zaehler == anzahl) {
			return true;
		} else {
			return false;
		}
	}
	
	
	private class ButtonHandler implements ActionListener {

		public void actionPerformed(ActionEvent arg0) {
			
			for(int i = 0; i < felder.length; i ++) {
				for(int j = 0; j < felder[i].length; j++) {
					
					felder[i][j].setZustand(0);
					felder[i][j].repaint();
					spieler = 1;
					spieleStatus.setText("Spieler 1");
					bt.stop();
					schalter = false;
					
				}
			}
		}
	}
	
private class MouseHandler extends MouseAdapter {
		
	public void mouseEntered(MouseEvent e) {
		
		for(int i = 0; i < einwurfsFelder.length; i++) {
				
			if(e.getSource() == einwurfsFelder[i]) {
				
				einwurfsFelder[i].setZustand(spieler);
				einwurfsFelder[i].repaint();
				
			}
				
		}
			
	} 
	
	public void mousePressed(MouseEvent e) {
			
		int reihe = 0;
			
		if(!gewonnen() && !unentschieden()) {
				
			for(int i = 0; i < einwurfsFelder.length; i++) {
					
				if(e.getSource() == einwurfsFelder[i]) {
						
					reihe = i;
						
				}
					
			}
			
			Feld[] slots = new Feld[felder[0].length];
			
			for(int i = 0; i < slots.length-1; i++) {
				slots[i] = felder[i][reihe];
			}
			wat = new WurfAnimationsThread(slots,spieler);

			synchronized(wat) {
				wat.start();
				try {
					wat.wait();
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}	
			}
			
			
			if(gewonnen()) {
						
				spieleStatus.setText("Spieler " + spieler + " hat gewonnen!");
					
			} else {
						
				if(!unentschieden()) {
							
				if(spieler == 1) {
							
					spieler = 2;
					spieleStatus.setText("Spieler 2");
					einwurfsFelder[reihe].setZustand(spieler);
					einwurfsFelder[reihe].repaint();
							
				} else {
							
					spieler = 1;
					spieleStatus.setText("Spieler 1");
					einwurfsFelder[reihe].setZustand(spieler);
					einwurfsFelder[reihe].repaint();
							
				}
						
				}else {
						
					spieleStatus.setText("Unentschieden!");
					
				}
			} 
					
		}	
	} 
	
	public void mouseExited(MouseEvent e) {
			
		for(int i = 0; i < einwurfsFelder.length; i++) {
			
			if(e.getSource() == einwurfsFelder[i]) {
					
				einwurfsFelder[i].setZustand(Feld.LEER);
				einwurfsFelder[i].repaint();
					
				}
				
			}
		
		}
	}
}
Java:
package vierGewinnt;

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;

/**
 * Feldklasse
 * 
 * Diese Klasse erbt von JPanel, und erweitert diese
 * um 2 Attribute und 3 Konstanten.
 * Sie hat 2 Konstruktoren und eine paint Methode.
 * Diese Klasse hat die Aufgabe einen Spielfeld dazustellen,
 * welches 3 Zustände haben kann.
 * 
 * 1) Ein leeres Spielfeld mit blauem Hintergrund
 * 
 * 2) Ein Spielfeld mit rotem Stein in der Mitte
 * 
 * 3) Oder ein Spielfeld mit gelben Stein in der Mitte
 * 
 * Das wird mit der Methode paint(Grahphics g) & einer Zustandsvariable realisiert.
 * Sie überprüft welchen Zustand das JPanel hat und zeichnet die einzelnen Komponent auf das Panel.
 * 
 * Weiters besitzt Sie für alle Attribute zugehörige Setter und Gettermethoden
 * 
 * @author  Rene Polak
 * @version 2010-11-17
 *
 */
public class Feld extends JPanel {

	// Statische Konstanten; Sie stellen die Zustände da die das Feld einnehmen kann
	public static final int LEER = 0; 
	public static final int ROT  = 1;
	public static final int GELB = 2;
	
	// Zustand den das Feld einnimmt
	private int zustand;
	// Hintergrundfarbe des Panels
	private Color hintergrund;
	
	/**
	 * Defaultkonstruktor
	 * 
	 * Erstellt ein leeres Feld. 
	 */
	public Feld() {
		
		this.zustand = LEER; // Der Zustand 0 bedeutet Leer
		this.hintergrund = Color.WHITE; 
		
	}
	
	/**
	 * Erstellt ein Feld mit Zustand & Hintergrundfarbe
	 * 
	 * @param zustand		status in dem sich das Feld befinden soll
	 * @param hintergrund	Farbe die der Hintergrund des Panels haben soll
	 * 
	 * 0 = Leer; 1 = Rot; 2 = Gelb
	 */
	public Feld(int zustand,Color hintergrund) {
		
		this.zustand = zustand;
		this.hintergrund = hintergrund;
		this.repaint(); // Das frisch erstelle Panel neuzeichnen
		
	}
	
	/**
	 * Zeichnet einen Spielstein oder einen leere Kreis in das JPanel je nach dem Zustand
	 * 0 = Weißer Kreis; 1 = Roter Spielstein; 2 = Gelber Spielstein
	 * 
	 * @param g		Graphics Objekt mit dem gezeichnet wird
	 */
	public void paint(Graphics g) {
	
		switch(this.zustand) { // Der interne Zustand;
		
			case LEER: // Wenn der Zustand Leer entspricht dann 
				
				 // Setzt die Farbe des Graphics-Objekt auf die Hintergrundfarbe im Objekt
				g.setColor(this.hintergrund);
				// Zeichnet ein Rechteck das bei 0,0 beginnt und so lang und so breit wie das Panel ist
				g.fillRect(0, 0, this.getWidth(), this.getHeight());
				// Setzt die Farbe des Graphics-Objekt auf Weiß
				g.setColor(Color.WHITE);
				// Zeichnet einen kreis der bei 0,0 beginnt und so lang und so breit wie das Panel ist
				g.fillOval(0,0,this.getWidth(),this.getHeight());
				
				break;
					
			case ROT: // Wenn der Zustand Rot entspricht dann
				
				 // Setzt die Farbe des Graphics-Objekt auf die Hintergrundfarbe im Objekt
				g.setColor(this.hintergrund);
				// Zeichnet ein Rechteck,welches bei 0,0 beginnt und so lang und so breit wie das Panel ist
				g.fillRect(0, 0, this.getWidth(), this.getHeight());
				// Setzt die Farbe des Graphics-Objekt auf Rot
				g.setColor(Color.RED);
				// Zeichnet einen roten Kreis, welcher bei 0,0 beginnt und so lang und so breit wie das Panel ist.
				g.fillOval(0,0,this.getWidth(),this.getHeight());
				// Setzt die Farbe des Graphics-Objekt auf Schwarz
				g.setColor(Color.BLACK);
				// Zeichnet 2 Schwarze Kreise, einen äußeren und einen etwas kleineren innen
				g.drawOval(0, 0, this.getWidth(), this.getHeight());
				g.drawOval(5, 5, (this.getWidth()-10), (this.getHeight()-10));
				
				break;
			
			case GELB: // Wenn der Zustand Rot entspricht dann
				
				 // Setzt die Farbe des Graphics-Objekt auf die Hintergrundfarbe im Objekt
				g.setColor(this.hintergrund);
				// Zeichnet ein Rechteck,welches bei 0,0 beginnt und so lang und so breit wie das Panel ist
				g.fillRect(0, 0, this.getWidth(), this.getHeight());
				// Setzt die Farbe des Graphics-Objekt auf Gelb
				g.setColor(Color.YELLOW);
				// Zeichnet einen gelben Kreis, welcher bei 0,0 beginnt und so lang und so breit wie das Panel ist.
				g.fillOval(0,0,this.getWidth(),this.getHeight());
				// Setzt die Farbe des Graphics-Objekt auf Schwarz
				g.setColor(Color.BLACK);
				// Zeichnet 2 Schwarze Kreise, einen äußeren und einen etwas kleineren innen
				g.drawOval(0, 0, this.getWidth(), this.getHeight());
				g.drawOval(5, 5, (this.getWidth()-10), (this.getHeight()-10));				
				
				break;
		}
		
	}
	
	/**
	 * Setzt den Zustand des JPanel und refresht den Inhalt anschließend
	 * 
	 * @param zustand		Zustand den das JPanel haben soll
	 */
	public void setZustand(int zustand) {
		
		this.zustand = zustand;
		this.repaint();
	}
	
	/**
	 * Gibt den Zustand des aktuellen JPanels zurück	
	 * 
	 * @return		int; Gibt den Zustand des JPanels zurück
	 * 
	 * 0 = Leer; 1 = Rot; 2 = GELB
	 */
	public int getZustand() {
		return this.zustand;
	}
	
	/**
	 * Setzt die Hintergrundfarbe des Obejekts 
	 * 
	 * @param hintergrund	Hintegrundfarbe die das Feld haben soll
	 */
	public void setHintergrund(Color hintergrund) {
		this.hintergrund = hintergrund;
	}
	
	/**
	 * Gibt die derzeitige Hintergrundfarbe des Obejkts zurück
	 * 
	 * @return				Color; Die Hintergrundfarbe des Objekts
	 */
	public Color getHintergrund() {
		return this.hintergrund;
	}
	
}
Java:
package vierGewinnt;

public class WurfAnimationsThread extends Thread {

	private Feld[] reihe;
	private int spieler;
	
	public WurfAnimationsThread() {
		
		this.reihe = new Feld[1];
		this.spieler = 1;
		
	}
	
	public WurfAnimationsThread(Feld[] reihe, int spieler) {
		
		this.reihe = reihe;
		this.spieler = spieler;
		
	}
	
	private boolean reiheIstVoll() {
		for(int i = 0; i < reihe.length; i++) {
			if((reihe[i].getZustand()==1) || (reihe[i].getZustand()== 2)) {
				return true;
			} else {
				return false;
			}
		}
		return false;
	}
	
	public void run() {
		if(!reiheIstVoll()) {
		for(int i = 0; i < reihe.length-1; i++) {
			if(reihe[i].getZustand() == 0) {
				reihe[i].setZustand(spieler);
				try {
					this.sleep(200);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				reihe[i].setZustand(Feld.LEER);
			}
		}
		for(int j = reihe.length-2; j >= 0; j--) {	
			if(reihe[j].getZustand()== 0) {	
				reihe[j].setZustand(spieler);
				break;		
			}		
		}
	}
	synchronized(this) {
		this.notify();
	}
	}
	
}
Java:
package vierGewinnt;

/**
 * Blinkthread
 * 
 * Diese Klasse erbt von Thread.
 * Sie erweitert den Thread um 2 Attribute & 2 Konstruktoren
 * Sie hat die Aufgabe die Spielsteine die zum Sieg eines Spieler geführt haben, 
 * blinken zu lassen.Zuerst wartet der Thread 350 ms  und setzt dann den die Felder auf 0,
 * d.h Leer, wartet wieder 350 ms und setzt dann die Felder auf die Farbe des Gewinners, 
 * solange bis der Thread abgebrochen wird.
 * 
 * @author  Rene Polak
 * @version 2010-11-17
 */
public class BlinkThread extends Thread {

	// Beinhaltet die 4 Felder die zum Sieg eines Spielers geführt haben
	private Feld[] felder;
	// Der Gewinner der Partie (ist für die setZustand() Methode wichtig)
	private int gewinner;
	
	/**
	 * Defaultkonstruktor
	 */
	public BlinkThread() {
		this.felder = new Feld[3];
		this.gewinner = 1;
	}
	
	/**
	 * Diese Konstruktor erstellt ein BlinkThread mit einem Feld[] und dem gewinner der Partie.
	 * Das Feld[] felder beinhaltet dabei die Spielsteine die blinken sollen.
	 * 
	 * @param felder		Array welches die Steine beinhaltet die blinken sollen
	 * @param gewinner		Gewinner der Partie (Ist für den zweiten Zustand beim Blinken wichtig)
	 */
	public BlinkThread(Feld[] felder,int gewinner) {
		
		this.felder = felder;
		this.gewinner = gewinner;
		
	}
	
	public void run() {
		
		while(true) { // Endlosschleife
			
			
			// Der Thread versucht 350 ms zu warten
			try {
				
				this.sleep(350); // Lässt den Thread 350 ms "schlafen" 
				
			} catch (InterruptedException e) { // Wenn etwas schief geht die entsprechende Meldung ausgeben
				
				e.printStackTrace(); // Fehlermeldung
				
			}
			
			// Zustand der Felder auf Leer setzen und neuzeichnen
			felder[0].setZustand(0);
			felder[0].repaint();
			felder[1].setZustand(0);
			felder[1].repaint();
			felder[2].setZustand(0);
			felder[2].repaint();
			felder[3].setZustand(0);
			felder[3].repaint();
			
			// Der Thread versucht 350 ms zu warten
			try {
				
				this.sleep(350); // Lässt den Thread 350 ms "schlafen" 
				
			} catch (InterruptedException e) { // Wenn etwas schief geht die entsprechende Meldung ausgeben

				e.printStackTrace(); // Fehlermeldung
				
			}
			
			// Zustand der Felder auf den Zustand des Gewinners setzen und neuzeichnen
			felder[0].setZustand(gewinner);
			felder[0].repaint();
			felder[1].setZustand(gewinner);
			felder[1].repaint();
			felder[2].setZustand(gewinner);
			felder[2].repaint();
			felder[3].setZustand(gewinner);
			felder[3].repaint();
			
		}
		
	}
	
}
Java:
package vierGewinnt;

import javax.swing.JFrame;

/**
 * Frameklasse
 * 
 * Sie intialsiert das Panel und ist das Hauptfenster.
 * In ihr wird das Panel hineingeladen und angezeigt.
 * Weiters beinhaltet sie die main Methode welche das Frame ausführt
 * 
 * @author  Rene Polak
 * @version 2010-11-17
 */
public class VGFrame extends JFrame {
	
	// Das Panel, welches im Konstruktor in das Frame geladen wird
	private VGPanel vgp;
	
	/**
	 * Main methode
	 * 
	 * Sie führt das Programm aus durch intialisierung des VGFrames
	 * 
	 * @param args	String[]; Dieser Parameter binhaltet alle Argumente die über die Konsole übergeben wurden
	 */
	public static void main(String[] args) {
		new VGFrame(); // Initialisierung des JFrames
	}
	
	/**
	 * Defaultkonstruktor
	 */
	public VGFrame() {
		
		// Initialisieren des JPanels
		this.vgp = new VGPanel();
		//hinzufügen des JPanel zum Frame
		this.add(vgp);
		// Titel des JFrames setzen
		this.setTitle("Vier gewinnt");
		// Größe des JFrames setzen
		this.setSize(300,335);
		// Verhalten im Fall der SchließenOperation setzen ( In dem Fall das Fenster schließen)
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		// Größenveränderung ausstellen
		this.setResizable(false);
		// Das JFrame sichtbar setzen
		this.setVisible(true);
		
	}

}
 
Ich habe schon einiges Probiert. Mit einer Schalter Variable, mit Synchronisierung auf das Panel oder auf den Thread. Nichts hat funktioniert. hat jemand eine gute Idee? Ich muss es schaffen das Programm dazu zu bringen solange zu warten bis der Thread fertig ist. Also das er sich ausführt die Animation und erst dann weiter gearbeitet wird im Programm...


lg,

Vancold
 
Man könnte fragen: WER soll warten? (Also, welcher Thread?). Es sollen ja in erster Line wohl keine Eingaben möglich sein, solange der Animationsthread läuft.

Eine ziemlich hingehackte Möglicheit ist hier mal angedeutet: Das steht im VGPanel in der Umgebung von 'mousePressed'. Für "schöne", aufgeräumte Lösungen müßte man ein bißchen mehr rum-umstrukturieren, aber vielleicht wird der Ansatz deutlich, so dass du es dann "schöner" bei dir einbauen kannst....

Java:
    private volatile boolean animiere = false;


    public void mousePressed(MouseEvent e) {

        if (animiere)
        {
            System.out.println("Eeehy, wa't ma'n moment....");
            return;
        }

        int reihe = 0;

        if(!gewonnen() && !unentschieden()) {

            for(int i = 0; i < einwurfsFelder.length; i++) {

                if(e.getSource() == einwurfsFelder[i]) {

                    reihe = i;

                }

            }

            Feld[] slots = new Feld[felder[0].length];

            for(int i = 0; i < slots.length-1; i++) {
                slots[i] = felder[i][reihe];
            }
            wat = new WurfAnimationsThread(slots,spieler);


            final Thread w = wat;
            final int r = reihe;
            Thread hilfsThread = new Thread(new Runnable()
            {
                public void run()
                {
                    animiere = true;
                    w.start();

                    try
                    {
                        synchronized (w)
                        {
                            w.wait();
                        }
                    }
                    catch (InterruptedException e)
                    {
                        Thread.currentThread().interrupt();
                    }
                    animiere = false;
                    testeGewonnen(r);
                }
            });
            hilfsThread.start();

        }
    }


    private void testeGewonnen(int reihe)
    {
        // Einiges davon sollte eigentlich auf dem Event-Dispatch-Thread gemacht werden...
        if(gewonnen()) {

            spieleStatus.setText("Spieler " + spieler + " hat gewonnen!");

        } else {

            if(!unentschieden()) {

            if(spieler == 1) {

                spieler = 2;
                spieleStatus.setText("Spieler 2");
                einwurfsFelder[reihe].setZustand(spieler);
                einwurfsFelder[reihe].repaint();

            } else {

                spieler = 1;
                spieleStatus.setText("Spieler 1");
                einwurfsFelder[reihe].setZustand(spieler);
                einwurfsFelder[reihe].repaint();

            }

            }else {

                spieleStatus.setText("Unentschieden!");

            }
        }
    }
 
Danke für deine Hilfe... Ein paar kleine Bugs gibts noch zum beheben aber das ists im großen und ganzen.

Eine Frage hätte ich dennoch. Ich würde gerne das Programm nach dem MVC-Model strukturieren wie wäre dann der Aufbau?
Theoretisch weiß ich wie MVC funktioniert aber praktisch happerts noch ein bisschen. Kann mir da wer nen denkanstoß geben?
 
Die Frage ist so wenig konkret, dass ich (abgesehen von einem mehrseitigen Essay) nicht wüßte, was ich dazu schreiben sollte (außer eben "Forensuche" und irgendwelche Halb*igen Hinweise auf Suchmaschinen... 😳 )
 

Zurück
Oben