java - JavaFX : Button never sets a graphic -


edit :

a mcve version of code has been made debug it. reproduces bug. purpose of code doing memory game. means when turn, "open" card, one. if form pair, don't turned over, stay open. otherwise, turn them on , try find pair on next turn.

simply put, bug : when opening second card of turn , both cards don't form pair, second 1 never gets opened!

hopefully, version of code find bug, me lot!

i have put code on github : https://gist.github.com/anonymous/e866671d80384ae53b53 (and find attached @ end of question)


explanation of issue

i having fun on doing little memory game in javafx , came across strange behavior card click on (represented custom class extends button class) never changes image displayed.

normally, when click on card, "opens" changing graphic displays. strange , annoying thing happens in specific case.

the behavior of card correct when "open" first card of turn of player. works when "open" second 1 , both cards pair. sadly, doesn't work in case want open second card , doesn't match pair first one.

i modified button class adding opencard() , closecard() methods. methods set specific graphic on button-card.

i show code hard tell might part making behavior happen. more using eclipse can't possibly figure out how debug javafx app breakpoints (i using console prints) because app crash when reach breakpoints , start crawling through lines of code.


the code

firstly, modified button class :

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")); } 

}

now controller class, event set on mouseevent. there more code in controller (like checking if there pair), isn't issue here think problem @ line call method open card. use getsource() method here because cards arranged in gridpane , need know 1 has been clicked on.

@override public void handle(mouseevent event) {   //get card clicked on   card card = (card) event.getsource();   //open card   card.opencard();   //do more after this... 

}


that's pretty figure out.

as stated, tried check if method opencard() being called. comment printed in console showed up. added console printing before , after line set graphic , both showing up. can't know sure happens when app reaches setgraphic() line nothing showing in app (the card remains closed).

any hint because sinking in madness right now. thank in advance.


the mcve version of code

the card object : card.java

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 position of card   private int row;   private int column; //-------------------------------------------------   //constructor   public card(int row, int column){     //give cards specific color @ init     this.setbackground(new background(new backgroundfill(color.deepskyblue,         new cornerradii(6), null)));     this.settext("closed");     this.row = row;     this.column = column;   } //-------------------------------------------------   //open card   public void opencard(){          system.out.println("open");     //cards red when open     this.setbackground(new background(new backgroundfill(color.red,       new cornerradii(6), null)));     this.settext("open");   } //-------------------------------------------------   //close card   public void closecard(){     system.out.println("close");     //cards blue when closed     this.setbackground(new background(new backgroundfill(color.deepskyblue,         new cornerradii(6), null)));     this.settext("closed");   } //-------------------------------------------------   //getters row , column info   public int getrow() { return row; }   public int getcolumn() { return column; } } 

the main (includes view , start point of app) : main.java

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 , cards   gridpane gridcard = new gridpane();   static card [][] cardarray;   //the event handler   private static eventhandler<mouseevent> handler;   //the array remembers pairs , reminder of last open card   static int[][] indexarray;   static int index;   //boolean array check if card open   static boolean[][] isopen;   //number of pairs 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 event handler     handler = new controller();      //some formatting 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 , bool array     cardarray = new card [2][5];     indexarray = new int [2][5];     isopen = new boolean [2][5];     //adding cards our card array     for(int = 0; < 2; i++){       for(int j = 0; j < 5; j++){         cardarray[i][j] = new card(i, j);         //make buttons cards         cardarray[i][j].setprefheight(100);         cardarray[i][j].setprefwidth(70);         //register event         cardarray[i][j].addeventhandler(mouseevent.mouse_clicked, gamecontroller());         //add cards         gridcard.add(cardarray[i][j], j, i);         //set pairs (no randomness here)         indexarray[i][j] = j+1;       }     }     //print out indexes of cards     system.out.println("----------------");     system.out.println("card indexes :");     (int = 0; < indexarray.length; i++) {       system.out.println();       (int j = 0; j < 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 stage     primarystage.setscene(new scene(root));     primarystage.settitle("memory test");     primarystage.show();      } //-------------------------------------------------     //getter event handler   public static eventhandler<mouseevent> gamecontroller() {     return handler;   } //-------------------------------------------------   //getter, setter , "resetter" index   public static void resetindex() { index = 0; }   public static int getindex() { return index; }   public static void setindex(int i) {     index = i;   } //------------------------------------------------- } 

the controller : controller.java

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<mouseevent>{  //-------------------------------------------------   @override   public void handle(mouseevent event) {     //get card cas clicked on     card card = (card) event.getsource();      //if card open, don't     if (!main.isopen[card.getrow()][card.getcolumn()]) {       //open card       card.opencard();        //we opened first card of turn       if (main.getindex() == 0) {          //set card open         main.isopen[card.getrow()][card.getcolumn()] = true;         //remember index         main.setindex(main.indexarray[card.getrow()][card.getcolumn()]);         system.out.println("index: "+main.getindex());        //we opened second card       }else if (main.getindex() != 0) {          //check if pair         if (main.getindex() == main.indexarray[card.getrow()][card.getcolumn()]) {            //decrement number of pairs           main.pairs--;           //open second card           main.isopen[card.getrow()][card.getcolumn()] = true;           //reset index           main.resetindex();          }else{ //close both cards if isn't pair           //wait 0.7 second let player remember cards           try {             thread.sleep(700);           } catch (interruptedexception e) {             e.printstacktrace();           }           //close current card           card.closecard();           system.out.println("index : " + main.indexarray[card.getrow()][card.getcolumn()]);           main.isopen[card.getrow()][card.getcolumn()] = false;           //close first opened card looking @ index           //it closes both cards same index, doesn't matter           //as pair hasn't been found anyway           (int = 0; < main.indexarray.length; i++) {             (int j = 0; j < 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 index of last opened card           main.resetindex();         }       }     }      //check endgame     if (main.pairs == 0) {       //show dialog box       alert incorrectpairs = new alert(alerttype.information);       incorrectpairs.settitle("game over");       incorrectpairs.setheadertext("the game over");       incorrectpairs.setcontenttext("you found pairs, congrats!");       incorrectpairs.showandwait();     }   } //------------------------------------------------- } 

you're blocking ui thread thread.sleep(...). prevents pending changes being repainted, don't see first update @ all; see subsequent updates after pause complete.

the simplest way implement pause on ui thread use pausetransition javafx animation api. basically, do

pausetransition pause = new pausetransition(duration.millis(700)); pause.setonfinished(e -> {     // code execute after pause... }); pause.play(); 

in case, want disable user interface, user cannot click on during pause, like

pausetransition pause = new pausetransition(duration.millis(700)); pause.setonfinished(e -> {     card.closecard();      // ... etc...      card.getparent().setdisable(false); });  card.getparent().setdisable(true); pause.play(); 

Comments

Popular posts from this blog

PHP DOM loadHTML() method unusual warning -

python - How to create jsonb index using GIN on SQLAlchemy? -

c# - TransactionScope not rolling back although no complete() is called -