Swing JForm friert ein, bis eine Aktion beendet ist [duplizieren]

Diese Frage hat hier bereits eine Antwort:

Swing-Fenster wird eingefroren und zeigt keinen Inhalt an 1 Antwort

Ich möchte eine Java-Anwendung erstellen, die das Sortieren von Zusammenführungen mithilfe von Swing-Komponenten visualisiert. Bisher habe ich folgendes geschrieben:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class MergeSort extends JFrame {

    private int[] helper;

    private int[] heights;
    private JPanel mainPanel;
    private JTextArea[] areas;
    private JTextArea txtSpeed;
    private JLabel lblSpeed;
    private JButton btnStart;

    private Random rnd;

    private final int FRAME_HEIGHT = 550;
    private final int FRAME_WIDTH = 1100;

    private final int ELEMENTS_TO_SORT = 100;

    private final int BAR_WIDTH = 7;

    private final int SPACING = 10;

    private int SLEEP_TIME = 50;

    public MergeSort() {
        super("Merge Sort Visualisation");
        helper = new int[ELEMENTS_TO_SORT];
        mainPanel = new JPanel();
        mainPanel.setLayout(null);
        rnd = new Random();

        areas = new JTextArea[ELEMENTS_TO_SORT];

        heights = new int[areas.length];

        for (int i = 0; i < areas.length; i++) {
            areas[i] = new JTextArea();
            heights[i] = rnd.nextInt(FRAME_HEIGHT - 100);
            mainPanel.add(areas[i]);
            areas[i].setSize(BAR_WIDTH, heights[i]);

            areas[i].setLocation((i + 1) * SPACING,
                    FRAME_HEIGHT - areas[i].getHeight());
            areas[i].setText(toDigits(heights[i]));
        }

        btnStart = new JButton("Start");
        btnStart.addActionListener(
                new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        try {
                            setSleepTime(Integer.parseInt(txtSpeed.getText()));
                            sort();

                        } catch (NumberFormatException ex) {
                            //s
                        } catch (InterruptedException ex) {
                            //i
                        }

                    }
                }
        );

        mainPanel.add(btnStart);
        btnStart.setSize(100, 25);
        btnStart.setLocation(0, 25);

        txtSpeed = new JTextArea("50");
        mainPanel.add(txtSpeed);
        txtSpeed.setSize(100, 25);
        txtSpeed.setLocation(0, 0);

        lblSpeed = new JLabel("Sleep Time");
        mainPanel.add(lblSpeed);
        lblSpeed.setSize(100, 25);
        lblSpeed.setLocation(110, 0);

        this.add(mainPanel);

        this.setSize(FRAME_WIDTH, FRAME_HEIGHT);

    }

    private void setSleepTime(int x) {
        if (x >= 0) {
            SLEEP_TIME = x;
        } else {
            SLEEP_TIME = 0;
        }
    }

    public void sort() throws InterruptedException {
        mergesort(0, heights.length - 1);
    }

    private void mergesort(int low, int high) throws InterruptedException {

        if (low < high) {

            int middle = low + (high - low) / 2;

            mergesort(low, middle);

            mergesort(middle + 1, high);

            merge(low, middle, high);
        }
    }

    private void merge(int low, int middle, int high) throws InterruptedException {

        for (int i = low; i <= high; i++) {
            helper[i] = heights[i];
        }

        int i = low;
        int j = middle + 1;
        int k = low;

        while (i <= middle && j <= high) {
            if (helper[i] <= helper[j]) {
                heights[k] = helper[i];
                updateAreaX(k);

                Thread.currentThread().sleep(SLEEP_TIME);
                i++;
            } else {
                heights[k] = helper[j];
                updateAreaX(k);

                Thread.currentThread().sleep(SLEEP_TIME);
                j++;
            }
            k++;
        }
        // Copy the rest of the left side of the array into the target array
        while (i <= middle) {
            heights[k] = helper[i];
            updateAreaX(k);

            Thread.currentThread().sleep(SLEEP_TIME);
            k++;
            i++;
        }
    }

    private String toDigits(int a) {
        StringBuilder bdr = new StringBuilder();
        while (a > 0) {
            bdr.insert(0, Integer.toString(a % 10) + String.format("%n"));

            a /= 10;
        }
        if (bdr.length() > 0) {
            bdr.setLength(bdr.length() - 1);
        }

        return bdr.toString();
    }

    private void updateAreaX(int x) {

        areas[x].setSize(BAR_WIDTH, heights[x]);
        areas[x].setLocation(areas[x].getLocation().x,
                FRAME_HEIGHT - areas[x].getHeight() - 40);

        areas[x].setText(toDigits(heights[x]));
    }

    public static void main(String[] args) throws InterruptedException {

        MergeSort sorter = new MergeSort();
        sorter.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        sorter.setVisible(true);

    }
}

Das Problem ist, dass wenn ich auf die Start-Schaltfläche klicke, der gesamte JFrame einfriert, bis alles sortiert ist und dann das Ergebnis angezeigt wird. Wenn ich das nicht startesort() Methode über den Button aber schreibensorter.sort() in der public static void main () funktioniert es. Wie kann ich es reparieren? Ich denke, ich muss die Sortierung auf einen anderen Thread oder so setzen, aber ich habe keine Ahnung, wie.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage