# Vier Gewinnt



## chrisey (22. Jul 2012)

Hallo!

ich bin gerade dabei ein Vier gewinnt Spiel zu programmieren. Ich habe bisher drei Klassen: eine Start-Klasse, eine View-Klasse und eine Control-Klasse. Die GUI steht bereits grob, jetzt möchte ich dass bei Knopfdruck auf die Buttons in der oberen Reihe Steine erscheinen. Leider gibt es da vermute ich noch ein Problem bei der doppelten for-schleife. Könnt ihr mir weiterhelfen? 
Ein anderes Problem besteht gerade darin, dass auf den Buttons ein Pfeil angezeigt werden soll. Das entsprechende jpg liegt bereits in dem Package. Trotzdem wird nichts angezeigt. Vielen Dank!

Hier ist der Code:

View:


```
package Projekt.view;

import Projekt.controller.Controller;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import java.lang.String;
import javafx.geometry.Pos;
import javafx.scene.effect.Reflection;
import javafx.scene.image.*;
import javafx.scene.layout.HBox;
import javax.swing.text.IconView;
import javafx.scene.image.Image;


public class View extends Application
{  
  Controller controller;
  public Label spielfeld[][] = new Label[7][7];
  public Button buttons[][] = new Button[7][1];

  public static void main(String[] args)
  {
    launch(args);
  }
  
  public void start(Stage primaryStage)
  {
    controller = new Controller(this);
    //erstell neues Border Pane
    BorderPane pane = new BorderPane();
    //erstelle neues Grid Pane als Spielfeld
    GridPane grid = new GridPane();
    //bestimme Abstände zwischen den einzelnen Feldern
    grid.setHgap(2);
    grid.setVgap(2);
    pane.setMaxSize(400, 400);
    //Abstände des Grid im Fenster in Pixel: top,right,bottom,left
    grid.setPadding(new Insets(20, 30, 30, 20));
    
    // [B]-> hier vermute ich den Fehler[/B]
    for (int j = 0; j < 6; j++)
    {
      for (int i = 0; i < 7; i++)
      {
        spielfeld[i][j] = new Label();
        spielfeld[i][j].setId("Knopf" + i + j);
        spielfeld[i][j].setMinSize(28, 28);
        grid.add(spielfeld[i][j], i, (j + 1));
        spielfeld[i][j].setStyle("-fx-border-radius:19px;-fx-border-color: black;");
      }
    }

    for (int i = 0; i < 7; i++)
    {
     // Dieser Pfeil wird nicht angezeigt:
      Image imagePfeilrunter = new Image(getClass().getResourceAsStream("Pfeilrunter.png"));
      ImageView imageview = new ImageView(imagePfeilrunter);
      imageview.setScaleX(0.2);
      imageview.setScaleY(0.2);
      
      //erzeuge 7 Buttons in einer Reihe
      buttons[i][0] = new Button();
      buttons[i][0].setId("Knopf" + i + 0);
      buttons[i][0].setMinSize(30, 30);
      buttons[i][0].setMaxSize(30, 30);
      buttons[i][0].setGraphic(new ImageView(imagePfeilrunter));
      buttons[i][0].setOnAction(controller);
      grid.add(buttons[i][0], i, 0);
    }
    
    pane.setCenter(grid);
    
    Label label = new Label("12:00");
    label.setPrefSize(100, 20);
    label.setAlignment(Pos.CENTER);
    label.setStyle("-fx-background-color:	cornflowerblue;-fx-border-color:black;");
    HBox hbox = new HBox();
    hbox.setPadding(new Insets(10, 5, 5, 10));
    hbox.setSpacing(8);
    hbox.getChildren().add(label);
    hbox.setAlignment(Pos.CENTER);
    pane.setTop(hbox);
    
    Label label2 = new Label("Spieler 1: \n ");
    label2.setStyle("-fx-background-color:	cornflowerblue;-fx-border-color:black;");
    HBox hbox2 = new HBox();
    hbox2.setPadding(new Insets(10, 5, 5, 10));
    hbox2.setSpacing(8);
    hbox2.getChildren().add(label2);
    hbox2.setAlignment(Pos.TOP_LEFT);
    pane.setLeft(hbox2);
    
    Label label3 = new Label("Spieler 2: \n ");
    label3.setAlignment(Pos.TOP_RIGHT);
    label3.setStyle("-fx-background-color:	cornflowerblue;-fx-border-color:black;");
    HBox hbox3 = new HBox();
    hbox3.setPadding(new Insets(10, 5, 5, 10));
    hbox3.setSpacing(8);
    hbox3.getChildren().add(label3);
    hbox3.setAlignment(Pos.TOP_RIGHT);
    pane.setRight(hbox3);
    
    primaryStage.setScene(new Scene(pane));
    primaryStage.show();
    
  }
    public void setzeSpielfeld(int x, int y, String text )
    {
      this.spielfeld[x][y].setText(text);
    
      if (text.equals(" "))
      {
        spielfeld[x][y].setStyle ("-fx-base: #ff00ff;");        
      }
      else
      {
        spielfeld[x][y].setStyle ("-fx-base: #40e0d0;");          
      }   
    }
  
    public String holeSpielfeld (int x, int y)
    {
        return this.spielfeld[x][y].getText();     
    }
}
```

Controller:


```
package Projekt.controller;

import Projekt.view.View;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;



public class Controller implements EventHandler<ActionEvent>
{
  //Referenz auf die GUI
  View gui;
  String werIstDran = " ";

  public Controller(View gui)
  {
    this.gui = gui;
  }

 
  public void handle(ActionEvent event)
  {
   
    setzeKnopf(((Button) event.getSource()).getId());
  }

  private void setzeKnopf(String knopfID)
  {
    for (int i = 0; i < 7; i++)
    {
      // Ausloeser des Events ermitteln und mit den Buttons vergleichen
      if (knopfID.equals("Knopf" + i + 0))
      {
        for (int j=0; j>=6;j++)
        {
          if(gui.holeSpielfeld(i, j).equals("") || gui.holeSpielfeld(i, j)==null )
          {
            gui.setzeSpielfeld(i, j, werIstDran);
            wechsleSpieler();
            break;
          }
        }
      }
    }
   }
  
private void wechsleSpieler()
   {
if    (werIstDran.equals(" "))
    {
       werIstDran = "";
    }
else
    {
      werIstDran = " ";
    }
  }
}
```


----------



## chrisey (22. Jul 2012)

Habe es jetzt hinbekommen, das bei Knopfdruck abwechselnd ein "x" und ein "o" angezeigt werden. wie kann ich stattdessen die Labels farbig ausfüllen lassen?


----------



## chrisey (23. Jul 2012)

hat keiner einen Tipp?


----------



## Fu3L (23. Jul 2012)

lbl sei ein JLabel:

```
lbl.setBackground(Color.RED);
lbl.setOpaque(true);
```


----------



## chrisey (25. Jul 2012)

Danke für den Tipp. Ich hab es jetzt allerdings schon anders hinbekommen. Der CSS Befehl in der Methode setzeSpielfeld musste geändert werden in -fx-background-color: green bzw. yellow!

Inzwischen hänge ich an einem anderen Problem. Ich habe für das Spiel ein weiteres Fenster gebaut, welches dem Spieler gleich beim Start angezeigt werden soll. Dort kann er zunächst zwiscehn 1-Spieler-Modus und 2-Spieler Modus wählen. Anschließend soll durch den Button "Spiel starten" zu dem Vier Gewinnt Fenster gewechselt werden. Könnt ihr mir sagen wie das geht? Irgendwas muss doch in die handle-methode für den button damit die fenster verknüpft werden. nochmal zur info (falls das einen unterschied macht): ich arbeite mit javafx.


----------



## AngryDeveloper (25. Jul 2012)

Warum möchtest du dafür zwei Fenster machen? Fände ich als Nutzer etwas unhandlich.
Kannst du nicht die Auswahl des Modus beim Start im gleichen Fenster machen und nachdem ich eines ausgewählt habe, startet das Spiel?

Wenn du aber trotzdem 2 Fenster haben möchtest, dann musst du eine neue Stage erstellen.
Dieser Stage kannst du dann eine Modality setzen und auch einen anderen Style verpassen. Siehe hierzu die jfx2 API:
Stage (JavaFX 2.1)


----------



## chrisey (25. Jul 2012)

Wäre es denn einfacher das ganze mit nur einem Fenster zu machen? Sorry, ich bin noch ein blutiger Anfänger in der Materie. Wie müsste ich denn in diesem Fall vorgehen?


----------



## Fu3L (26. Jul 2012)

Du wechselst das JPanel aus.

JFrame.setContentPane(new GamePanel());

Dabei sei GamePanel eine Klasse die von JPanel erbt und die Spielkomponenten enthält.


----------

