Unfortunately, this is not so simple. Only the GUI thread should be allowed to update the GUI, so any other thread should redirect any updates to the GUI thread through SwingUtilities.InvokeLater . In your case, you can simply wrap the entire makeData method, since all it does is update the GUI:
thread = new Thread(new Runnable() { @Override public void run() { while (true) { SwingUtilities.InvokeLater(new Runnable() { public void run() { makeData(); } }); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } } });
Note that now the makeData code will execute in the GUI thread. In other cases, when you are doing other laborious work that is not related to the GUI, you should use InvokeLater more subtle way to keep the user interface flow as free as possible.
Edit : By looking more closely at my code, I noticed that all you do is synchronize the GUI update every 200 ms. You can make it a lot easier with javax.swing.Timer :
int delay = 200; //milliseconds ActionListener taskPerformer = new ActionListener() { public void actionPerformed(ActionEvent evt) { makeData(); } }; new Timer(delay, taskPerformer).start();
source share