Hello everyone,
To train, I wanted to make a small program to move a small rectangle by pressing the WASD keys.
The program works, except that when I hold a key to move the rectangle, after a second, auto-repeat starts up, and the rectangle motion accelerates. I want to prevent automatic repeat to activate, so that the rectangle moves at a constant speed when I hold a key and stops when I released.
Does anyone have a solution for this problem?
Thank you in advance!
Here is the ButtonMotion classe :
import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JButton; import javax.swing.KeyStroke; public class ButtonMotion extends JButton implements MouseListener{ Animation an = new Animation(); char a; boolean animated = false; private Thread t; private Action motion; private Action stop; public ButtonMotion(Animation an, char a){ super("Up"); this.an = an; this.a = a; this.addMouseListener(this); motion = new Motion(); stop = new Stop(); switch(a){ //The direction depends on the key case 'w' : an.getInputMap().put(KeyStroke.getKeyStroke(a), "MotionU"); an.getActionMap().put("MotionU", motion); break; case 's' : an.getInputMap().put(KeyStroke.getKeyStroke(a), "MotionD"); an.getActionMap().put("MotionD", motion); break; case 'a' : an.getInputMap().put(KeyStroke.getKeyStroke(a), "MotionL"); an.getActionMap().put("MotionL", motion); break; case 'd' : an.getInputMap().put(KeyStroke.getKeyStroke(a), "MotionR"); an.getActionMap().put("MotionR", motion); break; } switch(a){ //The motion is stopped when the key is released case 'w' : an.getInputMap().put(KeyStroke.getKeyStroke(87,0,true), "StopU"); an.getActionMap().put("StopU", stop); break; case 's' : an.getInputMap().put(KeyStroke.getKeyStroke(83,0,true), "StopD"); an.getActionMap().put("StopD", stop); break; case 'a' : an.getInputMap().put(KeyStroke.getKeyStroke(65,0,true), "StopL"); an.getActionMap().put("StopL", stop); break; case 'd' : an.getInputMap().put(KeyStroke.getKeyStroke(68,0,true), "StopR"); an.getActionMap().put("StopR", stop); break; } } private void go(){ while(animated){ int y = an.getPosY(); int x = an.getPosX(); switch(a){ case 'w' : y--; break; case 's' : y++; break; case 'a' : x--; break; case 'd' : x++; break; } an.setPosY(y); an.setPosX(x); an.repaint(); try { Thread.sleep(8); } catch (InterruptedException ex) { ex.printStackTrace(); } } } class PlayAnimation implements Runnable{ public void run(){ go(); } } private class Motion extends AbstractAction { public void actionPerformed( ActionEvent tf ) { animated = true; t = new Thread(new PlayAnimation()); t.start(); switch(a){ case 'w' : System.out.println("up"); break; case 's' : System.out.println("down"); break; case 'a' : System.out.println("left"); break; case 'd' : System.out.println("right"); break; } } } private class Stop extends AbstractAction { public void actionPerformed( ActionEvent tf ) { animated = false; System.out.println("Stop"); } } public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) { animated = true; t = new Thread(new PlayAnimation()); t.start(); } public void mouseReleased(MouseEvent e) { animated = false; } }
Here is the animation classe :
import java.awt.Color; import java.awt.Graphics; import javax.swing.JPanel; public class Animation extends JPanel{ private int posX = 145; private int posY = 145; public void paintComponent(Graphics g){ g.setColor(Color.white); g.fillRect(0,0,this.getWidth(), this.getHeight()); g.setColor(Color.blue); g.fillRect(posX, posY, 20, 30); } public int getPosX() { return posX; } public void setPosX(int posX) { this.posX = posX; } public int getPosY() { return posY; } public void setPosY(int posY) { this.posY = posY; } }
Here is the Window class :
import java.awt.BorderLayout; import java.awt.Color; import javax.swing.JFrame; import javax.swing.JPanel; public class Window extends JFrame{ private JPanel container = new JPanel(); private Animation an = new Animation(); private ButtonMotion left = new ButtonMotion(an, 'a'); private ButtonMotion right = new ButtonMotion(an, 'd'); private ButtonMotion up = new ButtonMotion(an, 'w'); private ButtonMotion down = new ButtonMotion(an, 's'); public Window(){ this.setTitle("First project !"); this.setSize(300,300); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setLocationRelativeTo(null); container.setBackground(Color.white); container.setLayout(new BorderLayout()); JPanel south = new JPanel(); JPanel center = new JPanel(); center.setLayout(new BorderLayout()); center.add(up, BorderLayout.NORTH); center.add(down, BorderLayout.SOUTH); south.add(left); south.add(center); south.add(right); container.add(south, BorderLayout.SOUTH); container.add(an, BorderLayout.CENTER); this.setContentPane(container); this.setVisible(true); } }
Here is the Test class :
public class Test { public static void main(String[] args) { Window win = new Window(); } }