0

I'm working on a dice simulator for class where clicking a button generates two random numbers and shows images of dice with the ImageView control.

Homework problem: Create a JavaFX application that simulates rolling a pair of dice. When the user clicks a button, the application should generate two random numbers, each in the range of 1 through 6, to represent the value of the dice. Use ImageView controls to display the dice.

I'm trying to use the setImage method to change the image of the die when the button is pressed but I keep getting the error "cannot find symbol". I think it has something to do with the scope of the variable or a lack of defining the variable but I'm a beginner at all this so I have no clue.

How do I get this to work properly? Am I on the right track and just need to fix a few errors or do I need to go about the task a completely different way?

Code:

import java.util.Random;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.control.Label;
import javafx.scene.control.Button;
import javafx.geometry.Pos;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import java.io.FileInputStream;


public class DiceSimulator extends Application
{
    
    private Label myLabel;

    public static void main(String[] args)
    {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage)
    {
        myLabel = new Label("Click the button to roll the dice.");
    
   
      Image diceImage1 = new Image(new FileInputStream("file:Java Chapter 12 Assignment PC 6/Dice/Die1.bmp"));   
        ImageView diceView1 = new ImageView(diceImage1);

        diceView1.setX(0);
        diceView1.setY(0);

        diceView1.setFitHeight(150);
        diceView1.setFitWidth(150);
        
        diceView1.setPreserveRatio(true);


      Image diceImage2 = new Image(new FileInputStream("file:Java Chapter 12 Assignment PC 6/Dice/Die1.bmp"));
      ImageView diceView2 = new ImageView(diceImage2);

        diceView2.setX(0);
        diceView2.setY(0);

        diceView2.setFitHeight(150);
        diceView2.setFitWidth(150);
        
        diceView2.setPreserveRatio(true);



        Button myButton = new Button("Roll the dice!");
        myButton.setOnAction(new ButtonClickHandler());

        VBox vbox = new VBox(10, myLabel, myButton, diceView1, diceView2);

        Scene scene = new Scene(vbox, 300, 100);
        
        vbox.setAlignment(Pos.CENTER);

        primaryStage.setScene(scene);

        primaryStage.setTitle("Dice Simulator");

        primaryStage.show();
    }

    class ButtonClickHandler implements EventHandler<ActionEvent>
    {
        @Override
        public void handle(ActionEvent event)
        {
       
        
         
            int dice1=(int)(Math.random()*6+1);
            int dice2=(int)(Math.random()*6+1);

            String imgpath1 = "file:Java Chapter 12 Assignment PC 6/Dice/Die" +dice1+ ".bmp";
            String imgpath2 = "file:Java Chapter 12 Assignment PC 6/Dice/Die" +dice2+ ".bmp";

            diceView1.setImage(new Image(new FileInputStream(imgpath1)));
            diceView2.setImage(new Image(new FileInputStream(imgpath2)));       


        }
    
    }

}

Code error:

DiceSimulator.java:93: error: cannot find symbol
            diceView1.setImage(new Image(new FileInputStream(imgpath1)));
            ^
  symbol:   variable diceView1
  location: class DiceSimulator.ButtonClickHandler
DiceSimulator.java:94: error: cannot find symbol
            diceView2.setImage(new Image(new FileInputStream(imgpath2)));       
            ^
  symbol:   variable diceView2
  location: class DiceSimulator.ButtonClickHandler
2 errors
Slaw
  • 37,820
  • 8
  • 53
  • 80
Newbie123
  • 1
  • 2
  • 1
    `diceView*` are not defined in the scope of `handle`, they are local variables of a method of the enclosing class of `ButtonClickHandler`. YOu can try to make them fields and not local variables. – Jean-Baptiste Yunès Jul 15 '23 at 19:35
  • 1
    "_I think it has something to do with the scope of the variable_" – This is absolutely right. The `diceView1` and `diceView2` variables are local to the `start` method, and so they cannot be referenced outside that method. There are a few ways you could fix this. (1) You could make those two local variables _instance fields_ of the `DiceSimulator` class. (2) Similarly, you could make them instance fields of the `ButtonClickHandler` class, then add a constructor which lets you pass references to the image views to the handler. (3) Use a _lambda expression_ for the on-event handler. – Slaw Jul 15 '23 at 19:36
  • 1
    Note the first approach only works because your `ButtonClickHandler` is an inner class (i.e., a _non-static_ nested class). If it were a static nested class, then it wouldn't be able to directly reference instance fields of its enclosing class. Also, assuming your images are _resources_, you may want to read [How do I determine the correct path for FXML files, CSS files, Images, and other resources needed by my JavaFX Application?](https://stackoverflow.com/q/61531317/6395627). – Slaw Jul 15 '23 at 19:38
  • After I make diceView1 and diceView2 instance fields in either the Dice Simulator or ButtonClickerHandler class, how would I make sure they are still apart of the overall scene? Do both the Image and ImageView have to be created in the same class together or can they be in separate classes? – Newbie123 Jul 15 '23 at 21:28
  • So long as you have a reference to the appropriate `ImageView` instance, you can call `setImage(...)` on it from anywhere you like (as long as it's done on the _JavaFX Application Thread_, at least if the `ImageView` is part of a "live" scene graph). And no, the `Image` does not need to be created alongside the `ImageView`. – Slaw Jul 16 '23 at 00:53

0 Answers0