Java 线程运行不正常
我制作了一个简单的Java程序,它使用Thread对象在JPanel周围移动一个正方形。正方形移动到随机位置,更改其颜色,JPanel更改其背景色。然后线程休眠1000毫秒。但是,我又添加了一行代码,将+1添加到JLabel中,正方形停止移动(当分数起作用并添加+1时) 代码如下:Java 线程运行不正常,java,multithreading,swing,Java,Multithreading,Swing,我制作了一个简单的Java程序,它使用Thread对象在JPanel周围移动一个正方形。正方形移动到随机位置,更改其颜色,JPanel更改其背景色。然后线程休眠1000毫秒。但是,我又添加了一行代码,将+1添加到JLabel中,正方形停止移动(当分数起作用并添加+1时) 代码如下: @Override public void run() { Random random = new Random(); int width = 0; int height = 0;
@Override
public void run() {
Random random = new Random();
int width = 0;
int height = 0;
while(true) {
width = random.nextInt(area.getSize().width) + 1;
height = random.nextInt(area.getSize().height) + 1;
width -= ((width - 45) > 0) ? 45 : 0;
height -= ((height - 45) > 0) ? 45 : 0;
this.square.setLocation(width, height);
this.square.setIcon(new ImageIcon(getClass().getResource("/img/square" + (random.nextInt(4) + 1) + ".png")));
this.area.setBackground(new Color(random.nextInt(255) + 1, random.nextInt(255) + 1, random.nextInt(255) + 1));
//The following line works, but the setLocation method stops working.
this.score.setText(Integer.toString(Integer.parseInt(this.score.getText()) + 1));
try {
sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(RunThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
有什么想法吗
谢谢
编辑:这是我如何创建一个线程
public Click() {
initComponents();
pack();
setLocationRelativeTo(null);
setVisible(true);
RunThread run = new RunThread(jLabel1, jLabel2, jPanel1);
run.run();
}
在中调用run()方法
这是错误的。这不是使用线程的方法。如果调用run()
方法,那么它将与任何其他方法一样处理,并且您没有使用线程。因此,无论何时使用Thread.Sleep(…)
都会导致事件调度线程(EDT)
休眠,这意味着GUI无法重新绘制自身
要使用线程
。您需要调用Thead
上的start()
方法,因此代码应该是:
run.start();
在中调用run()方法
这是错误的。这不是使用线程的方法。如果调用run()
方法,那么它将与任何其他方法一样处理,并且您没有使用线程。因此,无论何时使用Thread.Sleep(…)
都会导致事件调度线程(EDT)
休眠,这意味着GUI无法重新绘制自身
要使用线程
。您需要调用Thead
上的start()
方法,因此代码应该是:
run.start();
可能线程超载了?从哪里开始线程?也就是说,实际上是启动线程还是只调用run()方法?发布一篇演示问题的正确文章。如何设置此。最初如何设置的文本?除非将其设置为包含整数的字符串,integer.parseInt
将失败。我在另一个类的构造函数中调用run()方法。因此,我创建了thread对象的一个实例,将一个JPanel和两个JLabel作为参数传递,然后调用run()方法。实际上,我使用Integer.parseInt将+1添加到当前JLabel文本中,然后将其返回到Integer.toString,因此它再次转换为字符串。我知道这可能不是一个好办法。。但这只是为了让我可以练习线程。我最近才知道。可能线程超载了?从哪里开始线程?也就是说,实际上是启动线程还是只调用run()方法?发布一篇演示问题的正确文章。如何设置此。最初如何设置的文本?除非将其设置为包含整数的字符串,integer.parseInt
将失败。我在另一个类的构造函数中调用run()方法。因此,我创建了thread对象的一个实例,将一个JPanel和两个JLabel作为参数传递,然后调用run()方法。实际上,我使用Integer.parseInt将+1添加到当前JLabel文本中,然后将其返回到Integer.toString,因此它再次转换为字符串。我知道这可能不是一个好办法。。但这只是为了让我可以练习线程。我最近了解到了这一点。您还应该注意,在事件分派线程之外修改Swing组件是一种非常糟糕的做法。这样,你会得到绘画错误和其他可怕的东西。如果需要进行繁重的计算或处理,可以使用单独的线程,但在修改swing组件时,必须使用SwingUtilities返回EDT。invokeLater()感谢您的解释camickr。现在一切正常!您还应该注意,在事件分派线程之外修改Swing组件是一种非常糟糕的做法。这样,你会得到绘画错误和其他可怕的东西。如果需要进行繁重的计算或处理,可以使用单独的线程,但在修改swing组件时,必须使用SwingUtilities返回EDT。invokeLater()感谢您的解释camickr。现在一切正常!