0

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();
    }
}
Loligans
  • 497
  • 9
  • 24

1 Answers1

2
  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.

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373