Reputation: 136
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.
Upvotes: 1
Views: 758
Reputation: 18792
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();
Upvotes: 2
Reputation: 32535
You are doing the sorting AND the sleeping in EDT
@Override
public void actionPerformed(ActionEvent arg0)
{
bubbleSort(array);
}
This is so called "GUI" thread and actionPerformed
is done by it. EDT is responsible for drawing and responsiveness of the UI. You are chocking it, thus freeze. Use SwingWorker
to do computation (and sleeping) and publish
intermediate results so the GUI may reflect the changes.
Upvotes: 1
Reputation: 424
You are placing Thread.sleep(500); directly on UI thread. Instead create new thread for bubble sort. So if you put sleep on thread other than UI thread it will not freeze your UI.
Upvotes: 2