Ernestas Gruodis
Ernestas Gruodis

Reputation: 8787

Thread.sleep called in loop - what is the proper way to use the delay while repainting the component?

I have created the loop, which periodically repaints component:

public class A extends Thread {

  private Component component;
  private float scaleFactors[];
  private RescaleOp op;

  public A (Component component){
  this.component = component;
  }

  public void run(){

    float i = 0.05f;
    while (true) {

        scaleFactors = new float[]{1f, 1f, 1f, i};
        op = new RescaleOp(scaleFactors, offsets, null);

        try {
            Thread.sleep(timeout);
        } catch (InterruptedException ex) {
            //Logger.getLogger(...)
        }
        component.repaint();
        i += step;
      }

    }

}

But in this case I get the message (NetBeans 7.3.1):

Thread.sleep called in loop

Maybe there is better solution in this situation?

Upvotes: 0

Views: 1898

Answers (1)

Reimeus
Reimeus

Reputation: 159754

Swing is single threaded. Calling Thread.sleep in the EDTprevents UI updates.

I suggest using a Swing Timer instead. It was designed to interact with Swing components.

Timer timer = new Timer(timeout, new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
        component.repaint();
    }
});
timer.start();

Edit:

Stopping a timer from within its own ActionListener is typically done using

@Override
public void actionPerformed(ActionEvent e) {
    Timer timer = (Timer) e.getSource();
    timer.stop();
}

Upvotes: 6

Related Questions