-3

I've looked at all my notes and comments from old code but I don't understand why it doesn't work.

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import java.util.Stack;
import javafx.scene.layout.VBox;

public class Main extends Application{

    Stage window;//makes window a stage
    Scene scene1, scene2;//makes scene1 and scene2 into Scene's
        public static void main(String []args) {

        //launches the main 
        launch(args);
    }
    @Override//Overrides Application
    public void start(Stage primaryStage) throws Exception {
        window = primaryStage;//Makes window primary stage
        Label label1 = new Label ("This is the first scene!");//Makes a label
        Button button1 = new Button();//Declares button as a Button
        button1.setText("Click me for Scene 2");//Sets the text of the button
        button1.setOnAction(e -> window.setScene(scene2));
        //This say, on the action, change the scene

        VBox layout1 = new VBox(20);//Makes layout1 into a VBox 
        layout1.getChildren().addAll(label1, button1);//Adds the 'Children'
        scene1 = new Scene(layout1, 500, 400);//Sets up layout1

        Button button2 = new Button();//makes a second button
        button2.setText("Click me for scene 1");//sets the text for button2
        button2.setOnAction(e -> window.setScene(scene1));//When button 2 is click, it changes scene

        StackPane layout2 = new StackPane();//Makes a new StackPane layout
        layout2.getChildren().add(button2);//Adds button2 to the layout
        scene2 = new Scene (layout2, 500, 400);//Gives arguemnts for Scene2

        window.setScene(scene1);//Sets scene of the window stage 
        window.setTitle("This is a title");//Sets title
        window.show();//Shows the window

    }
}

Vs.

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import java.util.Stack;
import javafx.scene.layout.VBox;

public class Main extends Application{

    Stage window;//makes window a stage
    Scene scene1, scene2;//makes scene1 and scene2 into Scene's
        public static void main(String []args) {

        //launches the main 
        launch(args);
    }
    @Override//Overrides Application
    public void start(Stage primaryStage) throws Exception {
        window = primaryStage;//Makes window primary stage
        Label label1 = new Label ("This is the first scene!");//Makes a label
        Button button1 = new Button();//Declares button as a Button
        button1.setText("Click me for Scene 2");//Sets the text of the button
        button1.setOnAction(e -> window.setScene(scene2));
        //This say, on the action, change the scene

        VBox layout1 = new VBox(20);//Makes layout1 into a VBox 
        layout1.getChildren().addAll(label1, button1);//Adds the 'Children'
        Scene scene1 = new Scene(layout1, 500, 400);//Sets up layout1

        Button button2 = new Button();//makes a second button
        button2.setText("Click me for scene 1");//sets the text for button2
        button2.setOnAction(e -> window.setScene(scene1));//When button 2 is click, it changes scene

        StackPane layout2 = new StackPane();//Makes a new StackPane layout
        layout2.getChildren().add(button2);//Adds button2 to the layout
        Scene scene2 = new Scene (layout2, 500, 400);//Gives arguemnts for Scene2

        window.setScene(scene1);//Sets scene of the window stage 
        window.setTitle("This is a title");//Sets title
        window.show();//Shows the window

    }
}

The only thing I changed between the two was adding the word 'Scene':

scene1 = new Scene.... Works

vs

Scene scene2 = new Scene.... Doesn't work. Why is this?

  • 2
    Can you elaborate on what you means by "works" and "doesn't work?" You've posted a lot of code here and without knowing what error you're seeing and what you've done to try to fix it it's hard for us to provide any useful feedback. – templatetypedef Feb 04 '17 at 21:44

2 Answers2

0

You are shadowing your member variables and leaving them as null in the second code.

In other words, there's only 2 instances of a Scene in the first code, and 4 in the other

When you do this, it uses Main.this.scene2, not the local instance .

button1.setOnAction(e -> window.setScene(scene2));

If you did need to use the local instance, you need to declare it final and initialize before the action listener was set.

Community
  • 1
  • 1
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • 2
    It doesnt work because the local `Scene` initialization happens after the button `onAction` initialization, meaning the `scene1` and `scene2` referenced in the lambda expressions are the class level variables. Reversing the initialization order will fix the problem as well indeed. – n247s Feb 04 '17 at 21:53
  • Just noticed that – OneCricketeer Feb 04 '17 at 21:54
0

The reason putting Scene before them doesn't work is because you've already declared them, but not initialised them, as Scenes in the line Scene scene1, scene2 So you don't need to specify that again. It'd be like making an integer int a then initialising it int a = 1. That doesn't make sense, because a has already been defined as an int. And really, it's less of "it doesn't work" and more of "it doesn't make sense".

Lupus Nox
  • 138
  • 8