Java:如何在重新按下键之前不断重复某个动作?

时间:2017-11-02 10:35:28

标签: java

在我的程序中,矩阵(2d数组)内的数字随着键控制而移动。当用户按下空格键(键码32,这是我的代码中的案例旁边的数字)时,代码应该触发随机移动功能和重新绘制GUI的功能。两者都是创建和测试的,都有效。但是,我只是想不通如何让代码每秒都重复随机移动功能,直到空格键或其他键被按下。

提前感谢您的帮助!

Code-snippet(循环是一个静态布尔值,每当按下另一个键时,循环将被设置为false。仍然似乎不起作用......):

case 32:
        loop = !loop;
        do{
            m.moveRandomly();
            updateMatrix(m);

        }while(loop);
        break;

4 个答案:

答案 0 :(得分:1)

查看https://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html

创建javax.swing.Timer的全局变量,在main函数中创建一个ActionListener,创建一个Timer实例并启动它。当按下空格(或任何其他键)时,您可以使用KeyEvent停止它。

public static void main(String[] args) {
    ActionListener al = new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            m.moveRandomly();
            updateMatrix(m);
        }
    }
    javax.swing.Timer time = new Timer(1000, al);
    time.start();
}

注意:Java中有三个名为" Timer"。

的类

答案 1 :(得分:0)

您希望能够在同一时间处理事件。

首先,开始动作,将无限循环。

其次,停止动作,应该更改布尔值以停止第一个动作。

阅读Lesson: Concurrency in Swing。您将了解到您正在使用循环阻止EDT(事件派发线程)。由于这是捕获密钥的同一个线程,因此您正在阻止自己。

这里的想法是使用新线程循环,直到收到你的事件。

以下是使用线程的想法的简单示例:

一个按钮启动Thread,另一个按钮停止将布尔值设置为false。我的帖子只会每1/4附加一个JTextArea(这是非常好的,但这是基于原始代码的基本解决方案)

@Override
public void actionPerformed(ActionEvent arg0) {
    if(arg0.getSource() == btnStart){
        t.start();
    } else if(arg0.getSource() == btnStop){
        t.stopAction();
    }
}

private class CounterThread extends Thread {

    private boolean b;

    @Override
    public void run() {
        //activate the loop
        b = true;
        do{
            /* THE ACTION */
            try {
                Thread.sleep(250);
            } catch (InterruptedException e) {e.printStackTrace();}
        } while(b);
    }

    public void stopAction(){
        b = false;
    }
}

Swing提供一个基本相同的Timer类,请参阅The_Programmer's answer作为一个很好的例子。

答案 2 :(得分:0)

public class Demo {

static volatile boolean loop=false;

public static void main(String args[]){

    for(int i=0;i<2;i++){
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                CollectionsDemo cd = new CollectionsDemo();
                cd.test();
            }
        }); 
        t.start();
    }

}


private static void test(){
    switch(32){
    case 32:
        loop = !loop;
        do{
            System.out.println("**");

        }while(loop);
        break;

    }
}

}

你的循环变量在第一次设置后没有被设置(即循环没有结束)。上面是工作示例,你可以做这样的事情。

答案 3 :(得分:0)

开始一个等待你的新线程 用户按下的关键事件。在Runnable的run方法中 实例你实现你的密钥循环。按下一个键后你必须这样做 使用SwingUtilities.invokerLater方法,该方法本身期望实现Runnable实例。在其运行方法中,您可以调用moveRandomupdateMatrics方法。通过这种方式,draw方法的调用在Swing Event和Dispatch队列的末尾正确排队。必须这样做才能正确绘制。

 Thread thread = new Thread(new Runnable()
 {
  public void run() 
  {
    do
    {
      char key = System.in.read();
      switch (key)
      {
         // Wait for key events 
        case 32:
          SwingUtilities.invokeLater(new Runnable()
          public void run()
          {
             m.moveRandomly();
             updateMatrics();
          }
          break;
      }
    }
    Thread.sleep(100);
    while (!stopped)
  }
});
thread.start();

查看https://en.wikipedia.org/wiki/Event_dispatching_thread