Как обновить пользовательский интерфейс при использовании Thread.sleep - PullRequest
0 голосов
/ 14 февраля 2019

При запуске моего метода BubbleSort я хочу обновить панель, показывая точно, что происходит, однако панель зависает до тех пор, пока метод не завершит работу при использовании Thread.sleep.

Я слышал об использовании таймеров Swing иЯ знаю, как их использовать, но не знаю, как я мог бы реализовать их «средний метод» для приостановки и продолжения.

import java.awt.Color;
import java.awt.Font;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;

@SuppressWarnings("serial")
public class BubbleSort extends JPanel implements ActionListener
{  
    int swaps;
    int maxswaps;
    int[] array;
    JLabel arrayLabel;
    JLabel tipLabel = new JLabel();;

    private void bubbleSort(int[] array)
    {  
        maxswaps = (int) Math.pow(array.length,2);
        int tempnum = 0;  
        for(int i=0; i < array.length; i++)
        {  
            for(int num=1; num < (array.length-i); num++)
            {  
                if(array[num-1] > array[num])
                {  
                    tempnum = array[num-1];  
                    array[num-1] = array[num];  
                    array[num] = tempnum;  
                    tipLabel.setText("Swapping " + tempnum + " and " + array[num-1]);
                    arrayLabel.setText(Arrays.toString(array));
                    this.repaint();
                    swaps++;
                    try
                    {
                        Thread.sleep(500);
                        // this is where I want it to sleep         
                    }
                    catch (InterruptedException e)
                    {

                    }

                } 
            }  
        }  
    }  



    public static void moveToMiddle(JFrame frame)
    {
        GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
        int screenWidth = gd.getDisplayMode().getWidth();
        int screenHeight = gd.getDisplayMode().getHeight();
        frame.setBounds((screenWidth/2) - (frame.getWidth()/2), (screenHeight/2) - (frame.getHeight()/2), frame.getWidth(), frame.getHeight());
    }

    public static void main(String[] args)
    {  
        JPanel panel = new BubbleSort();
        panel.setLayout(null);
        panel.setBackground(Color.WHITE);
        panel.setFocusable(true);

        JFrame frame = new JFrame("Bubble Sort");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);        
        frame.setSize(800, 500);
        frame.setContentPane(panel);
        frame.setVisible(true);
        moveToMiddle(frame);
    }  

    public BubbleSort()
    {
        int arrayLength = 12;
        int maxNumber = 100;
        int minNumber = 0;

        array = new int[arrayLength]; 
        Random r = new Random();
        for(int i=0; i < array.length; i++)
        {
            int num = r.nextInt(maxNumber) + minNumber;
            array[i] = num;
        }

        arrayLabel = new JLabel(Arrays.toString(array));
        arrayLabel.setFont(new Font("Bahnschrift", Font.PLAIN, 35));
        arrayLabel.setBounds(100, 100, 600, 100);

        tipLabel.setBounds(100 , 250 , 600, 100);
        tipLabel.setFont(new Font("Bahnschrift", Font.PLAIN, 35));

        tipLabel.setVerticalAlignment(SwingConstants.CENTER);
        tipLabel.setHorizontalAlignment(SwingConstants.CENTER);

        arrayLabel.setVerticalAlignment(SwingConstants.CENTER);
        arrayLabel.setHorizontalAlignment(SwingConstants.CENTER);

        JButton startButton = new JButton("Start");
        startButton.addActionListener(this);
        startButton.setBounds(0,0,50,50);

        this.add(arrayLabel);   this.add(tipLabel); this.add(startButton);
    }

    @Override
    public void actionPerformed(ActionEvent arg0)
    {
        bubbleSort(array);
    }
}  

Я хочу, чтобы панель обновлялась во время работы метода, но при использовании он остается пустымпока метод не закончится.

Ответы [ 3 ]

0 голосов
/ 14 февраля 2019

Измените ActionListner, чтобы сортировка выполнялась в отдельном потоке:

@Override
public void actionPerformed(ActionEvent arg0)
{
    new Thread(()->bubbleSort(array)).start();
}

Для обновления пользовательского интерфейса с использованием потока Swing используйте: SwingUtilities.invokeLater(()->repaint()); вместо this.repaint();

0 голосов
/ 14 февраля 2019

Вы делаете сортировку И спите в EDT

   @Override
    public void actionPerformed(ActionEvent arg0)
    {
        bubbleSort(array);
    }

Это так называемый поток "GUI", и actionPerformed выполняется им.EDT отвечает за рисование и отзывчивость пользовательского интерфейса.Вы душите это, таким образом замерзаете.Используйте SwingWorker для вычисления (и спящего режима) и publish промежуточные результаты, чтобы графический интерфейс мог отражать изменения.

0 голосов
/ 14 февраля 2019

Вы размещаете Thread.sleep (500);непосредственно в потоке пользовательского интерфейса.Вместо этого создайте новую тему для пузырьковой сортировки.Таким образом, если вы поместите режим сна в поток, отличный от потока пользовательского интерфейса, он не остановит ваш пользовательский интерфейс.

...