Good evening people, I can't change the scenes here. I can not understand where the error. Can you tell me?

public class CanvasEx extends Application { final int size=1000, dot_size=10, up=1, right=2, down=3, left=4, w=1, d=2, s=3, a=4; int delay=100, length=2, dir=2, food_x, food_y, length_2=2, dir_2=2; Canvas canvas; GraphicsContext gc; int x[]=new int[size*size]; int y[]=new int[size*size]; int x_2[]=new int[size*size]; int y_2[]=new int[size*size]; Thread game; Stage st; Scene scene, scene2, scene3; Button b3, b2, b1; boolean lost=false; @Override public void start(Stage primaryStage) { Stage st; st=primaryStage; FlowPane root1 = new FlowPane(); FlowPane root2 = new FlowPane(); FlowPane root3 = new FlowPane(); root1.setVgap(10); root1.setStyle("-fx-background-color: tan;-fx-padding: 10px;"); root2.setVgap(10); root2.setStyle("-fx-background-color: tan;-fx-padding: 10px;"); root3.setVgap(10); root3.setStyle("-fx-background-color: tan;-fx-padding: 10px;"); canvas=new Canvas(size,size); gc=canvas.getGraphicsContext2D(); canvas.setFocusTraversable(true); root1.getChildren().add(canvas); startGame(); canvas.setOnKeyPressed(new EventHandler<KeyEvent>(){ @Override public void handle(KeyEvent e) { KeyCode key=e.getCode(); if(key.equals(KeyCode.UP) && dir!=down) dir=up; if(key.equals(KeyCode.DOWN) && dir!=up) dir=down; if(key.equals(KeyCode.LEFT) && dir!=right) dir=left; if(key.equals(KeyCode.RIGHT) && dir!=left) dir=right; if(key.equals(KeyCode.W) && dir_2!=s) dir_2=w; if(key.equals(KeyCode.S) && dir_2!=w) dir_2=s; if(key.equals(KeyCode.A) && dir_2!=d) dir_2=a; if(key.equals(KeyCode.D) && dir_2!=a) dir_2=d; } }); Scene scene = new Scene(root1, size, size); Scene scene2 = new Scene(root2, size, size); Scene scene3 = new Scene(root3, size, size); Label l1=new Label("SNAKE GAME"); Button b3=new Button("Restart"); Button b2=new Button("Main Menu"); Button b1=new Button("Start Game"); b1.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent t) { control(t); } }); b2.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent t) { control(t); } }); b3.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent t) { control(t); } }); root3.getChildren().add(b3); root3.getChildren().add(b2); root2.getChildren().add(l1); root2.getChildren().add(b1); primaryStage.setTitle("Hello World!"); primaryStage.setScene(scene2); primaryStage.show(); } public void draw(GraphicsContext gc){ gc.clearRect(0, 0, size, size); if(!lost){ //gc.setFill(Paint.valueOf("green")); //gc.fillOval(food_x, food_y, dot_size, dot_size); gc.setFill(Paint.valueOf("brown")); gc.fillOval(x[0], y[0], dot_size, dot_size); gc.setFill(Paint.valueOf("red")); for(int i=1; i<length; i++){ gc.fillOval(x[i], y[i], dot_size, dot_size); } gc.setFill(Paint.valueOf("black")); gc.fillOval(x_2[0], y_2[0], dot_size, dot_size); gc.setFill(Paint.valueOf("blue")); for(int i=1; i<length_2; i++){ gc.fillOval(x_2[i], y_2[i], dot_size, dot_size); } }else{ gc.setFill(Paint.valueOf("black")); gc.fillText("Game Over", size/2-50, size/2-15); st.setScene(scene3); game.stop(); } } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } public void control(ActionEvent t) { if (t.getSource()==b1) st.setScene(scene); if (t.getSource()==b3) st.setScene(scene); else if(t.getSource()==b2) st.setScene(scene2); } private void startGame() { length=2; length_2=2; for(int i=0; i<length; i++){ x[i]=50-i*dot_size; y[i]=50; } for(int i=0; i<length_2; i++){ x[i]=500-i*dot_size; y[i]=500; } //locateFood(); game=new Thread(new Runnable() { @Override public void run() { while(true){ if(!lost){ //checkFood(); checkCollision(); move(); length++; length_2++; } draw(gc); try{ Thread.sleep(delay); } catch(Exception e){}; } } }); game.start(); } private void locateFood() { food_x=(int)(Math.random()*((size/dot_size)-1))*dot_size; food_y=(int)(Math.random()*((size/dot_size)-1))*dot_size; } private void checkFood() { if(x[0]==food_x && y[0]==food_y){ length++; locateFood(); } if(x_2[0]==food_x && y_2[0]==food_y){ length_2++; locateFood(); } } private void checkCollision() { if(x[0]>=size || y[0]>=size) lost=true; if(x[0]<0 || y[0]<0) lost=true; if(x_2[0]>=size || y_2[0]>=size) lost=true; if(x_2[0]<0 || y_2[0]<0) lost=true; for(int i=2; i<length; i++) if(x[0]==x[i] && y[0]==y[i]) lost=true; for(int i=2; i<length_2; i++) if(x_2[0]==x_2[i] && y_2[0]==y_2[i]) lost=true; for(int i=0; i<length; i++) if(x[0]==x_2[i] && y[0]==y_2[i]) lost=true; for(int i=0; i<length_2; i++) if(x_2[0]==x[i] && y_2[0]==y[i]) lost=true; } private void move() { for(int i=length-1;i>0;i--){ x[i]=x[i-1]; y[i]=y[i-1]; } for(int i=length_2-1;i>0;i--){ x_2[i]=x_2[i-1]; y_2[i]=y_2[i-1]; } if(dir==up)y[0]-=dot_size; if(dir==down)y[0]+=dot_size; if(dir==right)x[0]+=dot_size; if(dir==left)x[0]-=dot_size; if(dir_2==w)y_2[0]-=dot_size; if(dir_2==s)y_2[0]+=dot_size; if(dir_2==d)x_2[0]+=dot_size; if(dir_2==a)x_2[0]-=dot_size; } 

}

    2 answers 2

    Honestly, I somehow did not notice in your example of an attempt to change the scene. But as a direct answer, here is an example of a code for changing scenes within the framework of some stages:

     public class Test extends Application { private Scene first; private Scene second; private Stage primaryStage; public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) throws Exception { first = new Scene(new Group(addEvent(new Button("first"))), 300, 300); second = new Scene(new Group(addEvent(new Button("second"))), 300, 300); primaryStage.setScene(first); (this.primaryStage = primaryStage).show(); } private Button addEvent(Button b) { b.setOnMouseClicked((e) -> { primaryStage.setScene(((Button) e.getSource()).getText() == "first" ? second : first); }); return b; } } 

    and in addition, listen to the comment @GVArt: with threads in JavaFx, not everything is so simple, for example, adding an object to the main stream happens by calling the static method of the Platform class:

     Platform.runLater(new Runnable() { @Override public void run() { //TODO something } }); 

    }

    which would be nice to wrap in Task

      It is not likely that you will succeed. Rewrite your Control method. Use only one scene and one FlowPane. And add all the Node to a new one in FlowPane.

       root.getChildrens().removeAll(); root.getChilderns().addAll(YOUR_ELEMENTS_THERE); 

      Objects do not re-re-create (if this is not required by logic) so as not to waste resources in vain. This will remove all items from the window and add new ones you need.