# Button neu einfärben



## ChristianEG (17. Apr 2010)

Aloha,

ich programmiere gerade für die FH ein Programm, welches wie 4 Gewinnt funktioniert. Es spielen 2 Menschen vor dem PC, wer zuerst 6 Buttons in einer Reihe (Diagonal, Horizontal oder Vertikal) verbindet hat gewonnen. 

Das klappt soweit Super. Allerdings muss ich am ende die Gewinnsituation farblich markieren. So das man am ende des Spiels sieht WIE gewonnen wurde. Das bekomme ich einfach nicht hin!

Hier mal meine Klassen:

*C6Button*

```
package vier;



import java.awt.Color;

import java.awt.GridLayout;

import javax.swing.JPanel;



public class C6Board extends JPanel {



	private static final long serialVersionUID = 1L;

	@SuppressWarnings("unused")

	private static int AnzahlButtons;

	private C6Button SpielButton;

	private C6Modell SpielRegeln;



	public C6Board(C6Modell modell) {

		super();

		SpielRegeln = modell;

		setLayout(new GridLayout(SpielRegeln.DIM_X, SpielRegeln.DIM_Y));

		AnzahlButtons = SpielRegeln.DIM_X * SpielRegeln.DIM_Y;



		for (int x = 0; x < SpielRegeln.DIM_X; x++) {

			for (int y = 0; y < SpielRegeln.DIM_Y; y++) {

				SpielButton = new C6Button(SpielRegeln, x, y);

				add(SpielButton);

			}

		}

		

	}

	

	public void neumalen() {

		SpielButton.setBackground(Color.red);

		System.out.println("repaaaint!");

	}

}
```

*C6Button*

```
package vier;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import vier.C6Modell.State;

public class C6Button extends JButton implements ActionListener {

	private static final long serialVersionUID = 1L;
	private C6Modell SpielRegeln;
	private int X;
	private int Y;

	public C6Button(C6Modell m, int x, int y) {
		super("");
		X = x;
		Y = y;
		SpielRegeln = m;
		addActionListener(this);
		setPreferredSize(new Dimension(50, 40));
	}


	public void actionPerformed(ActionEvent e) {
		getParent().repaint();
		if (SpielRegeln.StateAt(X, Y).equals(State.EMPTY) && SpielRegeln.gameOver == false) {
			
			if (SpielRegeln.getDrawing().equals(State.BLACK)) {
				setText("X");
				SpielRegeln.makeMove(X, Y);
				SpielRegeln.game[X][Y] = State.BLACK;
			} else {
				setText("O");
				SpielRegeln.makeMove(X, Y);
				SpielRegeln.game[X][Y] = State.WHITE;
			}
		}
	}
}
```

*C6Frame*

```
package vier;



import java.awt.BorderLayout;

import javax.swing.JFrame;



public class C6Frame extends JFrame {

	/**

     * 

     */

	private static final long serialVersionUID = 1L;



	public C6Frame(String Text) {

		super(Text);

		setLayout(new BorderLayout());

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		setSize(900, 900);

		setResizable(true);



		C6Modell SpielRegeln = new C6Modell();

		C6Board eins = new C6Board(SpielRegeln);

		getContentPane().add(eins, BorderLayout.CENTER);

		setVisible(true);

		pack();

		

	}

}
```

*C6Modell*

```
package vier;

import javax.swing.JOptionPane;

public class C6Modell {

	final int DIM_Y = 20;
	final int DIM_X = 20;
	final int WINNING = 6;
	private Direction[] dirs;
	private State drawing = State.BLACK;
	public State[][] game;
	private boolean[][] marked;
	public boolean gameOver = false;

	public enum State {
		EMPTY, BLACK, WHITE
	};

	public enum Direction {
		NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, SOUTHWEST, WEST, NORTHWEST
	};

	public C6Modell() {
		game = new State[DIM_X][DIM_Y];
		for (int a = 0; a < DIM_X; a++) {
			for (int b = 0; b < DIM_Y; b++) {
				game[a][b] = State.EMPTY;
			}
		}
		marked = new boolean[DIM_X][DIM_Y];
		for (int a = 0; a < DIM_X; a++) {
			for (int b = 0; b < DIM_Y; b++) {
				marked[a][b] = false;
			}
		}
	}

	public State getDrawing() {
		return drawing;
	}

	public boolean getMarked(int x, int y) {
		return marked[x][y];
	}

	public State StateAt(int x, int y) {
		return game[x][y];
	}

	public void makeMove(int x, int y) {
		
		if (drawing.equals(State.BLACK)) {
			game[x][y] = State.BLACK;
			drawing = State.WHITE;
		} else {
			game[x][y] = State.WHITE;
			drawing = State.BLACK;
		}
		if (testWinningCondition()) {
			gameOver = true;
			//JOptionPane.showMessageDialog(null, "Das Spiel ist gewonnen","GameOver", JOptionPane.WARNING_MESSAGE);
			//System.exit(0);
		}

	}

	public boolean testWinningCondition() {
		for (Direction dirs : Direction.values()) {
			int x = 0;
			int y = 0;

			for (y = 0; y < DIM_Y; y++) {
				for (x = 0; x < DIM_X; x++) {
					genericSearch(x, y, dirs);
					if (gameOver == true)
						return true;
				}
			}

		}
		return gameOver;
	}

	public void genericSearch(int x, int y, Direction dirs) {
		int deltaX = 0;
		int deltaY = 0;
		State value = StateAt(x, y);
		
		if (value == State.EMPTY)
			return;

		switch (dirs) {
		case NORTH:
			deltaX = 0;
			deltaY = 1;
			break;

		case SOUTH:
			deltaX = 0;
			deltaY = -1;
			break;

		case WEST:
			deltaX = -1;
			deltaY = 0;
			break;

		case EAST:
			deltaX = 1;
			deltaY = 0;
			break;

		case NORTHEAST:
			deltaX = +1;
			deltaY = +1;
			break;

		case SOUTHEAST:
			deltaX = +1;
			deltaY = -1;
			break;

		case NORTHWEST:
			deltaX = -1;
			deltaY = +1;
			break;

		case SOUTHWEST:
			deltaX = -1;
			deltaY = -1;
			break;
		}

		int count = 1;
		
		for (int i = 1; i < WINNING; i++) {
			x += deltaX;
			y += deltaY;

			if (y < DIM_Y && x < DIM_X && x > 0 && y > 0) {
				State toCheck = StateAt(x, y);

				if (value == toCheck) {
					//System.out.println("TO CHECK " + toCheck + " value " + value);
					count++;
				}
			}
		}
		
		//System.out.println(count);
		if(count == WINNING){
			//System.out.println("ich hab gewonnen");
			for (int i = 1; i < WINNING; i++) {
				x -= deltaX;
				y -= deltaY;

				if (y < DIM_Y && x < DIM_X && x > 0 && y > 0) {
					State toCheck = StateAt(x, y);

					if (value == toCheck) {
						//System.out.println("TO CHECK " + toCheck + " value " + value);
						marked[x][y] = true;
						//System.out.println(x + " comein and findout " + y);
					}
				}
			}		
		}
		gameOver = count == (WINNING);
	}
}
```


*C6Runner*

```
package vier;

public class C6Runner {

	public static void main(String[] args) {
		@SuppressWarnings("unused")
		C6Frame main = new C6Frame("Main Window");
	}
}
```

Das ist alles so nach Vorgabe und funktioniert auch soweit, bis auf das Einfärben der Buttons nach einem Gewinn.

Irgendwie muss ich nach jedem Klick (wohl in der makeMove Methode) überprüfen lassen ob marked(x,y) == true ist und dann den Button neufärben. Allerdings bekomm ich das nicht hin. Sitze da jetzt schon ewig dran.

Hat jemand eine Idee? Wäre klasse.

Gruß,
Christian


EDIT:
Hab mir auch schon folgendes Thread durchgelesen:
http://www.java-forum.org/java-basics-anfaenger-themen/34850-java-lang-nullpointerexception.html
Dort wird anhand von Repaint(); neugezeichnet bzw. eingefärbt. Allerdings klappt das so bei mir auch nicht. ;/


----------



## agentone (17. Apr 2010)

Suchst du das hier? 


```
JButton btn=new JButton("Text");
btn.setBackground(Color.BLUE);
```

Siehe: JComponent (Java 2 Platform SE v1.4.2)


----------



## XHelp (17. Apr 2010)

Habe mich zwar nicht gründlichst durch den Code durchgearbeitet, aber:
Du überprüfst ja alles im model. und model hängt nicht wirklich mit der grafischen Darstellung zusammen. Und es ist einfacher die Buttons als Referenz festzuhalten (z.B. 2 dimensionales Array). Dann kannst du die auch nachträglich einfärben.


----------

