Expectation
There is an ArrayList that has 3 Images. There are 3 ImageViews. There is a button. When the button is pressed, each ImageView is continuously updated with an Image from the ArrayList of Images. (continuously iterate in the ArrayList and update the view with the next image) Like a slot machine in a casino. When I press the button again. ImageViews should stop updating images.
My Code
package slotMachine;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
public class TestClass extends Application{
//3 ImageView
static ImageView view1= new ImageView();
static ImageView view2= new ImageView();
static ImageView view3= new ImageView();
//3 Images
static Image image1 = new Image("file:resources/bell.png");
static Image image2 = new Image("file:resources/cherry.png");
static Image image3 = new Image("file:resources/lemon.png");
static Button button = new Button("Press");
//ArrayList holding the 3 images
static ArrayList<Image> array = new ArrayList<Image>();
static boolean spinning = false;
@Override
public void start(Stage primaryStage) throws Exception {
//add images to the arrayList
array.add(image1);
array.add(image2);
array.add(image3);
HBox outerBox = new HBox();
outerBox.getChildren().addAll(view1, view2, view3, button);
button.setOnAction(event -> spin());
Scene scene = new Scene(outerBox, 1000, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void spin(){
if(spinning){
spinning = false;
}
else {
spinning = true;
}
//Create 3 threads to spin images in 3 different ImageViews
SpinClass r1 = new SpinClass(array, view1);
Thread t1 = new Thread(r1);
t1.start();
SpinClass r2 = new SpinClass(array, view2);
Thread t2 = new Thread(r2);
t2.start();
SpinClass r3 = new SpinClass(array, view3);
Thread t3 = new Thread(r3);
t3.start();
}
public static void main(String[] args){
launch(args);
}
}
class SpinClass implements Runnable{
ArrayList<Image> arr;
ImageView view;
public SpinClass(ArrayList<Image> arr, ImageView view) {
this.arr = arr;
this.view = view;
}
@Override
public void run() {
Collections.shuffle(arr); //shuffle images in array
int position = 0;
//spin images in current ImageView until button is pressed again.
while (TestClass.spinning){
view.setImage(arr.get(position));
view.setPreserveRatio(true);
view.setFitWidth(100);
view.setFitHeight(100);
position = (position + 1) % arr.size();
try {
TimeUnit.MILLISECONDS.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Outcome
I don't get a consistent outcome.
Sometimes I only get one view that is updating the images.
Sometimes all 3 images are updating. Another time only two images are updating or all 3 starts to update but one or two stop without me pressing the button.
Also, I tried creating 3 different arraylists instead of all threads accessing the same ArrayList. But the problem persists.
array1.add(new Image("file:resources/bell.png"));
array1.add(new Image("file:resources/cherry.png"));
array1.add(new Image("file:resources/lemon.png"));
array2.add(new Image("file:resources/bell.png"));
array2.add(new Image("file:resources/cherry.png"));
array2.add(new Image("file:resources/lemon.png"));
array3.add(new Image("file:resources/bell.png"));
array3.add(new Image("file:resources/cherry.png"));
array3.add(new Image("file:resources/lemon.png"));