Loligans
Loligans

Reputation: 507

How to wait until a thread completes its work

I have a movement thread that listens for movement. I can let it run through the while loop, but when there is no movement taking place, the Thread goes to 100% CPU usage because its just going through the while loop over and over.

What I am trying to do is put that Thread to sleep AFTER it finishes it's animation, and wake it up when I press a key

When I press an arrow key, I will move in a direction until I let go. At which point the movementThread waits, but when I press another key, or the same key, the keyListener doesn't respond. The Keylistener doesn't respond, because when I call

waitMovementThread();

it never leaves the synchronized object. Idk whats wrong, or how I should fix this situation.

private void keyListeners(){
    GlobalObjects.frame.addKeyListener(new KeyListener() {
        @Override
        public void keyPressed(KeyEvent e) {

            //Up    = 38
            //Down  = 40
            //Left  = 37
            //Right = 39
            System.out.println("Keypressed");
            if(e.getKeyCode() == 16){
                player.setPlayerMovementSpeed(3);
            }
            if(e.getKeyCode() == 38){
                notifyMovementThread();
                player.setPlayerMovement(1);
            }else if(e.getKeyCode() == 40){
                notifyMovementThread();
                player.setPlayerMovement(2);
            }else if(e.getKeyCode() == 37){
                notifyMovementThread();
                player.setPlayerMovement(3);
            }else if(e.getKeyCode() == 39){
                notifyMovementThread();
                player.setPlayerMovement(4);
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {
            if(e.getKeyCode() == 16){
                player.setPlayerMovementSpeed(10);
            }
            if(e.getKeyCode() == 38){
                if(player.getPlayerMovement() != 1){

                }else{
                    player.setPlayerMovement(0);
                    waitMovementThread();
                }
            }else if(e.getKeyCode() == 40){
                if(player.getPlayerMovement() != 2){

                }else{
                    player.setPlayerMovement(0);
                    waitMovementThread();
                }
            }else if(e.getKeyCode() == 37){
                if(player.getPlayerMovement() != 3){

                }else{
                    player.setPlayerMovement(0);
                    waitMovementThread();
                }
            }else if(e.getKeyCode() == 39){
                if(player.getPlayerMovement() != 4){

                }else{
                    player.setPlayerMovement(0);
                    waitMovementThread();
                }
            }
        }

        @Override
        public void keyTyped(KeyEvent e) {

        }
    });
}
private void waitMovementThread(){
    synchronized(movementThread){
        try {
            movementThread.wait();
        } 
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
private void notifyMovementThread(){
    synchronized(movementThread){
        movementThread.notify();
    }
}

Upvotes: 0

Views: 202

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285415

  1. Don't tie up the GUI event thread with a while (true) or a wait(). Your GUI will freeze (not sure at this point if you're doing this or not).
  2. If a Swing application, don't use a KeyListener, but rather use Key Bindings. The tut's will show you how.
  3. Use a Swing Timer in place of your while or wait. Start the Timer on key press and stop it on key release. There are many examples of this to be found on this site and others, several written by me in fact.

For example, have a look at this question's answer code, including camickr's, Trashgod's and mine.

Upvotes: 2

Related Questions