在我的程序中,矩阵(2d数组)内的数字随着键控制而移动。当用户按下空格键(键码32,这是我的代码中的案例旁边的数字)时,代码应该触发随机移动功能和重新绘制GUI的功能。两者都是创建和测试的,都有效。但是,我只是想不通如何让代码每秒都重复随机移动功能,直到空格键或其他键被按下。
提前感谢您的帮助!
Code-snippet(循环是一个静态布尔值,每当按下另一个键时,循环将被设置为false。仍然似乎不起作用......):
case 32:
loop = !loop;
do{
m.moveRandomly();
updateMatrix(m);
}while(loop);
break;
答案 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实例。在其运行方法中,您可以调用moveRandom
和updateMatrics
方法。通过这种方式,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();