-2

I'm stuck at this problem. I have to visualize Selection Sort Algorithm in Java, I decided to use JavaFX for UI. In my code, I have array of numbers and array of buttons. I used buttons to see the output of number array step by step. But I only get output result when all the loop process ends. I want to do it like this example: https://algorithm-visualizer.org/brute-force/selection-sort

I searched about it and know that I have to use threads but I couldn't handle it. Can you please help me?

@FXML
private void btnTik(ActionEvent event){
    Action action = new Action();
    new Thread(){
        public void run(){
    for(int i = 0 ; i < nums.length ; i++){
            min = i;
            for(int j = i+1 ; j < nums.length ; j++){
                if(nums[j] < nums[min]){
                    min = j;
                    btn[i].setText(Integer.toString(nums[i]));
                    action.sleep(200); //Thead.sleep(200)
                }
                btn[i].setText(Integer.toString(nums[i]));
                action.sleep(200);
            }
            nums = action.Degistir(nums, i, min);

                btn[i].setText(Integer.toString(nums[i]));
                action.sleep(200);
            System.out.println(nums[i]+" ");
    }
        }
    }.run();

}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 3
    Some problems: **(1)** See [What is the difference between Thread.start() and Thread.run()?](https://stackoverflow.com/q/2674174/6395627). **(2)** If you fix number one then you'll be updating the UI on a background thread; **never** do this, a live UI must only be interacted with on the FX thread. **(3)** I don't believe you need a thread for this, the animation API should be sufficient; see [JavaFX periodic background task](https://stackoverflow.com/q/9966136/6395627). – Slaw Apr 21 '20 at 21:50
  • Thank you, but I still can't understand how can I use it with nested for loop(I mean replacing my loops into animations) – Andarkan Apr 21 '20 at 22:34
  • See https://en.wikipedia.org/wiki/Event-driven_programming and https://en.wikipedia.org/wiki/State_pattern – Slaw Apr 21 '20 at 22:43
  • *I decided to use JavaFX * - so why did you include the "Swing" tag? – camickr Apr 21 '20 at 23:41

2 Answers2

1

The following is an mre of swapping two Labels in an array of Labels in a row. JavaFx animation tools are the right tools for the job. This example uses PauseTransition:

import java.util.Random;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Duration;

public class FxMain extends Application {

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setScene(new Scene(new ReelPane()));
        primaryStage.show();
    }

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

class ReelPane extends GridPane {

    private final Label[] tiles;

    private static final int PAUSE = 3, NUM_OF_TILES = 5;

    ReelPane() {
        tiles = new Label[NUM_OF_TILES];
        setPadding(new Insets(5));
        setHgap(10);
        setVgap(10);

        for(int index = 0; index < NUM_OF_TILES; index++){
            Label tile = new Label(String.valueOf(index));
            tile.setPrefSize(100,100);
            tile.setStyle("-fx-border-color: red;");
            tile.setFont(new Font("Arial", 30));
            tile.setAlignment(Pos.CENTER);
            tiles[index]=tile;
            add(tile, index, 0);
        }
        swap();
    }

    public void swap() {

        Random rand = new Random();

        PauseTransition pause = new PauseTransition(Duration.seconds(PAUSE));
        pause.setOnFinished(event ->{

            int index1 = rand.nextInt(NUM_OF_TILES);
            int index2 = rand.nextInt(NUM_OF_TILES);
            if(index1 != index2){
                String tempText = tiles[index1].getText();
                tiles[index1].setText(tiles[index2].getText());
                tiles[index2].setText(tempText);
            }
            pause.play();
        });

        pause.play();
    }
}
c0der
  • 18,467
  • 6
  • 33
  • 65
-1

But I only get output result when all the loop process ends

This is because you call run() on the Thread so it doesn't actually create a new thread. Instead it runs on the main UI thread and never allows the UI to update.

I think that multithreading isn't a good solution for what you want to do because you will have to figure out how to communicate with the UI thread to tell it to update. When I did something similar in Swing many years ago, I used callbacks in my sorting algorithm to signal the UI to update.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268