When running my BubbleSort method I want a panel to update showing exactly what is happening, however the panel freezes until the method has fniished when using Thread.sleep.
I've heard about using Swing timers and I know how to use them but do not know how I could implement them 'mid-method' to pause and continue.
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);
}
}
I want the panel to update whilst the method is running but using it remains blank until the method has finished.
Change the ActionListner
so the sorting is done on a separate thread:
@Override
public void actionPerformed(ActionEvent arg0)
{
new Thread(()->bubbleSort(array)).start();
}
To update UI using Swing thread use : SwingUtilities.invokeLater(()->repaint());
instead of this.repaint();