Thread.sleep() stopping my paint?

拟墨画扇 提交于 2019-12-17 21:01:45

问题


I'm making a program that is trying to animate a card moving across the screen as if you actually drew it from a desk. Here is the code for the animating:

public void move(int x, int y) {
    int curX = this.x; //the entire class extends rectangle
    int curY = this.y;

    // animate the movement to place
    for (int i = curX; i > x; i--) {
        this.x = i;
    }

    this.x = x;
    this.y = y;
}

this rectangle object is inside of a panel inside of a jframe. for repainting the panel, i have this:

public void run() {
    while (Core.isRunning()) {
        gamePanel.repaint(); //panel in which my rectangle object is in

        try {
            Thread.sleep(50);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

this is a thread, repainting the gamePanel every 50 milliseconds.

Now, I realize this may not be the best way to do this sort of thing. if there is a better way to do this whole repainting thing, please inform me!

But, the problem i'm having is when i call the move() command for my rectangle, it goes through the thread, but the image isnt updating till the end, so it's just a jump from point a to the final location.

why is this happening? can anyone critique/improve my code? thanks!


回答1:


The problem is you call Thread.sleep() in the Event Dispatch Thread causing the GUI become unresponsive. To avoid this you may want to use Swing Timer instead:

   Timer timer = new Timer(50, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            if(!stop) {
                gamePanel.repaint();
            } else {
                ((Timer)e.getSource()).stop();
            }
        }
    });
    timer.setRepeats(true);
    timer.setDelay(50);
    timer.start();

Where stop is a boolean flag that indicates the animation must stop.




回答2:


Most probably, the forloop in method move() is running so fast you don't see any transitions. The simplest way to solve this is adding a sleep within the loop in the move() method, such as:

public void move(int x, int y) {
    int curX = this.x; //the entire class extends rectangle
    int curY = this.y;

    // animate the movement to place
    for (int i = curX; i > x; i--) {
        this.x = i;
        Thread.sleep(20); // Just experiment with other sleep amounts
    }
    this.x = x;
    this.y = y;
}

Regarding the repainting logic, it is generally inefficient to have a separate thread redraw everything at each cycle, mainly because you could be repainting things that haven't actually changed. It is usually more efficient to update only the things that change.

In a complex situation in which several shapes overlap each other, you would need to determine what changes and what doesn't, because if something doesn't move but is overlapped by something that does, you would need to update the overlapped shape as well to ensure it is drawn correctly. There are sofisticated algortihms that address just this problem, but if your scene does not have many shapes then it could be simpler to just redraw everything when something changes.



来源:https://stackoverflow.com/questions/21652914/thread-sleep-stopping-my-paint

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!