0
votes

I made an app where you search for numbers in a specific order. This is how it looks : enter image description here

Currently, I have put the numbers in a specific order. How could I randomize this? For example, I want each button to change all the location of the buttons everytime a button is clicked. Problem is that GridPane can stack the nodes in one place, making the buttons hide behind eachother. Is there a way to set that the nodes cannot stack?

On the other hand , I found a method from a post where someone wanted to switch the location of two buttons. The code looked like this :

public static void swap(Node button1, Node button2) {
    Integer temp = GridPane.getRowIndex(button1);
    GridPane.setRowIndex(button1, GridPane.getRowIndex(button2));
    GridPane.setRowIndex(button2, temp);

    temp = GridPane.getColumnIndex(button1);
    GridPane.setColumnIndex(button1, GridPane.getColumnIndex(button2));
    GridPane.setColumnIndex(button2, temp);

}

I tried to make an arraylist which contains the nodes, and then using math.random to get a random index from the arraylist , which then gets a random button.

public static ArrayList<Node> buttonList = new ArrayList<Node>();

and the code to randomize the index :

public static int maxListValue = 19;
public static int minListValue = 0;
public static int listRandom = (int) (Math.random() * maxListValue) + minListValue;

Then, using the swap method, I tried :

swap(buttonList.get(listRandom), buttonList.get(listRandom));

this doesn't work for some reason, the button does nothing when I put random on the first node, however, if I change it to specify the first node , like : swap(buttonOne, buttonList.get(listRandom)); then it works, but calling the method for multiple buttons does not work, it only works on the first line of the method.

Would appreciate any tips on why this is not working

2
listRandom is set only once, so the value always remains the sameDaniel
Yes but how does this affect the swap method? why doesn't it work to put random on both node arguments?Ruthless
The "Math.random()"-Method is called only once, when the JVM loads the class. Make "listRandom" a method, then it should work.Daniel
You can use the ideas from here. You just need to replace Circle with Button.\Sedrick

2 Answers

2
votes

You need to remove the selected place from the arraylist after calling it and then recalculate it listRandom. You could do it like this:

Random random = new Random();
public static Node listRandom() {
    Node place = buttonList.get(random.nextInt(buttonList.size());
    buttonList.remove(place);
    return place;
}

or if you don't want to remove the entry to make it possible to swap a place multiple times:

public static Node listRandom() {
    return buttonList.get(random.nextInt(buttonList.size());
}

and then you could call it with:

swap(listRandom(), listRandom());
0
votes

Another thing you could do is use Collections.shuffle to randomize the list.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Control;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @author blj0011
 */
public class App extends Application
{

    Random random = new Random();
    int numberOfRows = 5;
    int numberOfColumns = 4;

    @Override
    public void start(Stage primaryStage)
    {
        List<Button> buttonList = new ArrayList();
        for (int i = 0; i < numberOfColumns * numberOfRows; i++) {
            Button button = new Button(Integer.toString(i + 1));
            button.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
            buttonList.add(button);
        }

        GridPane gridPane = new GridPane();
        addButtonsToGridPane(gridPane, buttonList);
        gridPane.setPadding(new Insets(20, 20, 20, 20));

        Button btn = new Button();
        btn.setText("Press Me!");
        btn.setOnAction((ActionEvent event) -> {
            Collections.shuffle(buttonList);//Shuffle the List of Circles.
            for(int i = 0; i < numberOfColumns * numberOfRows; i++) 
            { 
                Button c = buttonList.get(i); 
                GridPane.setColumnIndex(c, i % numberOfColumns); 
                GridPane.setRowIndex(c, i / numberOfColumns); 
            }
        });

        VBox vBox = new VBox(gridPane, new StackPane(btn));
        vBox.setMaxSize(Control.USE_COMPUTED_SIZE, Control.USE_COMPUTED_SIZE);
        StackPane root = new StackPane(vBox);
        root.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
        Scene scene = new Scene(root);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }

    public void addButtonsToGridPane(GridPane gridPane, List<Button> buttonsList)
    {
        for (int i = 0; i < numberOfColumns * numberOfRows; i++) {
            gridPane.add(buttonsList.get(i), i % numberOfColumns, i / numberOfColumns);
        }
    }
}