title: JavaFX : Button never sets a graphic
body: <h2>EDIT :</h2>
  
  <p>A MCVE version of my code has been made to help debug it. It reproduces my bug. The purpose of my code is doing a Memory game. Which means that when it is your turn, you "open" a card, then another one. If they form a pair, they don't get turned over, they stay open. Otherwise, you turn them back over and try to find a pair on the next turn.</p>
  
  <p>Simply put, the bug is : when you are opening the second card of your turn and both cards don't form a pair, the second one never gets opened!</p>
  
  <p>Hopefully, this version of my code will help you to find the bug, which will help me a lot!</p>
  
  <p>I have put the code on Github : <a href="https://gist.github.com/anonymous/e866671d80384ae53b53" rel="nofollow">https://gist.github.com/anonymous/e866671d80384ae53b53</a>
  (And you will find it <em>attached</em> at the end of the question)</p>
  
  <hr>
  
  <h2>Explanation of the issue</h2>
  
  <p>I am having fun on doing a little Memory game in JavaFX and I came across this strange behavior where the card I click on (represented by a custom class that extends the Button class) never changes the image displayed.</p>
  
  <p>Normally, when I click on the card, it "opens" itself by changing the graphic it displays.
  The strange and annoying thing is that it only happens in a specific case.</p>
  
  <p>The behavior of my card is correct when I "open" the first card of the turn of the player. It also works when I "open" a second one and both cards are a pair. Sadly, it doesn't work only in the case where I want to open a second card and it doesn't match as a pair with the first one.</p>
  
  <p>I modified the Button class by adding <code>openCard()</code> and <code>closeCard()</code> methods. Those methods will set a specific graphic on the button-card.</p>
  
  <p>I will now show some code but it is hard to tell what might be the part that is making this behavior happen. Even more so that I am using Eclipse but can't possibly figure out how to debug a JavaFX app with breakpoints (I am using console prints) because the app will eventually crash when I reach my breakpoints and start crawling through the lines of code.</p>
  
  <hr>
  
  <h2>The code</h2>
  
  <p>Firstly, the modified Button class :</p>
  
  <pre><code>public class Card extends Button{
  private String cardDesign;
  
  public Card(int row, int column){
    this.setGraphic(new ImageView("/resources/card_back.png"));
    this.setBackground(new Background(new BackgroundFill(Color.SLATEGRAY,
        new CornerRadii(6), null)));
  }
  
  public void setOpenCardDesign(String design){ cardDesign = design; }
  
  public void openCard(){ this.setGraphic(new ImageView(cardDesign)); }
  
  public void closeCard(){
    this.setGraphic(new ImageView("/resources/card_back.png"));
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Now the controller class, the event is set on a <code>MouseEvent</code>. There is more code in this controller (like checking if there is a pair), but this isn't an issue here I think as the problem is already at the line where I call the method to open the card.
  I use the  <code>getSource()</code> method here because my cards are arranged in a gridPane and I need to know which one has been clicked on.</p>
  
  <pre><code>@Override
  public void handle(MouseEvent event) {
    //Get the card that was clicked on
    Card card = (Card) event.getSource();
    //Open the card
    card.openCard();
    //Do some more after this...
  </code></pre>
  
  <p>}</p>
  
  <hr>
  
  <p>That's pretty much it as from what I could figure out.</p>
  
  <p>As already stated, I tried to check if the method <code>openCard()</code> is being called. It is as some comment printed in my console showed up. I even added some console printing just before and just after the line where I set the graphic and they both are showing up. I can't know for sure what happens when my app reaches the <code>setGraphic()</code> line as nothing is showing up in my app (the card remains closed).</p>
  
  <p>Any hint would help because I am slowly sinking in madness right now.
  Thank you in advance.</p>
  
  <hr>
  
  <h2>The MCVE version of my code</h2>
  
  <p><strong>The card object</strong> : <code>Card.java</code></p>
  
  <pre><code>package memory;
  
  import javafx.scene.control.Button;
  import javafx.scene.layout.Background;
  import javafx.scene.layout.BackgroundFill;
  import javafx.scene.layout.CornerRadii;
  import javafx.scene.paint.Color;
  
  public class Card extends Button{
  //-------------------------------------------------
    //Store the position of the card
    private int row;
    private int column;
  //-------------------------------------------------
    //Constructor
    public Card(int row, int column){
      //Give the cards a specific color at init
      this.setBackground(new Background(new BackgroundFill(Color.DEEPSKYBLUE,
          new CornerRadii(6), null)));
      this.setText("CLOSED");
      this.row = row;
      this.column = column;
    }
  //-------------------------------------------------
    //Open the card
    public void openCard(){     
      System.out.println("OPEN");
      //Cards are red when open
      this.setBackground(new Background(new BackgroundFill(Color.RED,
        new CornerRadii(6), null)));
      this.setText("OPEN");
    }
  //-------------------------------------------------
    //Close the card
    public void closeCard(){
      System.out.println("CLOSE");
      //Cards are blue when closed
      this.setBackground(new Background(new BackgroundFill(Color.DEEPSKYBLUE,
          new CornerRadii(6), null)));
      this.setText("CLOSED");
    }
  //-------------------------------------------------
    //Getters for row and column info
    public int getRow() { return row; }
    public int getColumn() { return column; }
  }
  </code></pre>
  
  <p><strong>The main (includes the view and start point of the app)</strong> : <code>Main.java</code></p>
  
  <pre><code>package memory;
  
  import javafx.application.Application;
  import javafx.event.EventHandler;
  import javafx.geometry.Insets;
  import javafx.geometry.Pos;
  import javafx.scene.Scene;
  import javafx.scene.input.MouseEvent;
  import javafx.scene.layout.Background;
  import javafx.scene.layout.BackgroundFill;
  import javafx.scene.layout.BorderPane;
  import javafx.scene.layout.CornerRadii;
  import javafx.scene.layout.GridPane;
  import javafx.scene.paint.Color;
  import javafx.stage.Stage;
  
  public class Main extends Application {
  
  //-------------------------------------------------  
    //The layout and the cards
    GridPane gridCard = new GridPane();
    static Card [][] cardArray;
    //The event handler
    private static EventHandler&lt;MouseEvent&gt; handler;
    //The array which remembers the pairs and the reminder of last open card
    static int[][] indexArray;
    static int index;
    //Boolean array to check if the card is already open
    static boolean[][] isOpen;
    //Number of pairs to find
    static int pairs = 5;
  //-------------------------------------------------
    //Cheap main
    public static void main(String[] args) {
      Application.launch(args);
    }
  //-------------------------------------------------
    @Override
    public void start(Stage primaryStage) throws Exception {
  
      //Init the event handler
      handler = new Controller();
  
      //Some formatting for the grid pane
      gridCard.setHgap(10);
      gridCard.setVgap(10);
      gridCard.setPadding(new Insets(0, 10, 0, 10));
      gridCard.setAlignment(Pos.CENTER);
  
      //Creating our card board, index array and bool array
      cardArray = new Card [2][5];
      indexArray = new int [2][5];
      isOpen = new boolean [2][5];
      //Adding the cards to our card array
      for(int i = 0; i &lt; 2; i++){
        for(int j = 0; j &lt; 5; j++){
          cardArray[i][j] = new Card(i, j);
          //Make those buttons look like cards
          cardArray[i][j].setPrefHeight(100);
          cardArray[i][j].setPrefWidth(70);
          //Register the event
          cardArray[i][j].addEventHandler(MouseEvent.MOUSE_CLICKED, gameController());
          //Add those cards
          gridCard.add(cardArray[i][j], j, i);
          //Set the pairs (no randomness here)
          indexArray[i][j] = j+1;
        }
      }
      //Print out the indexes of all the cards
      System.out.println("----------------");
      System.out.println("Card indexes :");
      for (int i = 0; i &lt; indexArray.length; i++) {
        System.out.println();
        for (int j = 0; j &lt; indexArray[0].length; j++) {
          System.out.print(indexArray[i][j]+ " | ");
        }
        System.out.println();
      }
      System.out.println("----------------");
  
      //Set BorderPane
      BorderPane root = new BorderPane();
      root.setBackground(new Background(new BackgroundFill(Color.BLACK,
          CornerRadii.EMPTY, null)));  
      root.setCenter(gridCard);   
  
      //Set the stage
      primaryStage.setScene(new Scene(root));
      primaryStage.setTitle("Memory Test");
      primaryStage.show();
  
  
  
    }
  //-------------------------------------------------  
    //Getter for the event handler
    public static EventHandler&lt;MouseEvent&gt; gameController() {
      return handler;
    }
  //-------------------------------------------------
    //Getter, Setter and "resetter" for the index
    public static void resetIndex() { index = 0; }
    public static int getIndex() { return index; }
    public static void setIndex(int i) {
      index = i;
    }
  //-------------------------------------------------
  }
  </code></pre>
  
  <p><strong>The controller</strong> : <code>Controller.java</code></p>
  
  <pre><code>package memory;
  
  import javafx.event.EventHandler;
  import javafx.scene.control.Alert;
  import javafx.scene.control.Alert.AlertType;
  import javafx.scene.input.MouseEvent;
  
  public class Controller implements EventHandler&lt;MouseEvent&gt;{
  
  //-------------------------------------------------
    @Override
    public void handle(MouseEvent event) {
      //Get the card which cas clicked on
      Card card = (Card) event.getSource();
  
      //If the card was already open, don't do anything
      if (!Main.isOpen[card.getRow()][card.getColumn()]) {
        //Open the card
        card.openCard();
  
        //We opened the first card of the turn
        if (Main.getIndex() == 0) {
  
          //Set the card as open
          Main.isOpen[card.getRow()][card.getColumn()] = true;
          //Remember the index
          Main.setIndex(Main.indexArray[card.getRow()][card.getColumn()]);
          System.out.println("index: "+Main.getIndex());
  
        //We opened the second card
        }else if (Main.getIndex() != 0) {
  
          //Check if it is a pair
          if (Main.getIndex() == Main.indexArray[card.getRow()][card.getColumn()]) {
  
            //Decrement the number of pairs
            Main.pairs--;
            //Open the second card
            Main.isOpen[card.getRow()][card.getColumn()] = true;
            //Reset the index
            Main.resetIndex();
  
          }else{ //Close both cards if it isn't a pair
            //Wait 0.7 second to let the player remember the cards
            try {
              Thread.sleep(700);
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
            //Close the current card
            card.closeCard();
            System.out.println("index : " + Main.indexArray[card.getRow()][card.getColumn()]);
            Main.isOpen[card.getRow()][card.getColumn()] = false;
            //Close the first opened card by looking at the index
            //It closes both cards with the same index, but it doesn't matter
            //as the pair hasn't been found anyway
            for (int i = 0; i &lt; Main.indexArray.length; i++) {
              for (int j = 0; j &lt; Main.indexArray[0].length; j++) {
                if (Main.getIndex() == Main.indexArray[i][j]) {
                  Main.cardArray[i][j].closeCard();
                  System.out.println("index: " + Main.indexArray[i][j]);
                  Main.isOpen[i][j] = false;
                }
              }
            }
            //Reset the index of last opened card
            Main.resetIndex();
          }
        }
      }
  
      //Check endgame
      if (Main.pairs == 0) {
        //Show a dialog box
        Alert incorrectPairs = new Alert(AlertType.INFORMATION);
        incorrectPairs.setTitle("GAME OVER");
        incorrectPairs.setHeaderText("The game is over");
        incorrectPairs.setContentText("You found all the pairs, congrats!");
        incorrectPairs.showAndWait();
      }
    }
  //-------------------------------------------------
  }
  </code></pre>