我想知道如何线程化以下代码,或者只是一般的方法:
public void run (){
public void paint(Graphics g) {
g.fillRect(20, 20, 20, 20);
for (int i = 20; i < 1000; i++) {
g.fillRect(20, i, 20, 20);
Thread.sleep(10);
}
}
}
我发现我无法创建此代码的线程,因为我遇到了表达式错误的非法开始,这很公平,但我没有找到解决方法。
最佳答案
很难说清楚自己在做什么,
但您似乎正试图覆盖 paint()
的 Runnable
从其内部 run()
方法。
这肯定是做不到的。
逻辑是
- 拿一个组件
- 重写它的paint方法来绘制我们需要的东西
- 调用方法来更新矩形的坐标(或者在这种情况下计时器会这样做)
- 比电话
repaint()
在组件上,因此可以再次调用 paint 方法并使用其新坐标重绘矩形(Timer 也会在更改 Rectangle 的坐标后负责重绘) - 根据需要/需要多次重复最后 2 个步骤
(当我说组件时,我实际上是指 JPanel
,绘制方法指的是重写 paintComponent(..)
的 JPanel
,因为这是最佳实践。)
一些建议:
1) 不要覆盖 paint
而是使用 JPanel
并覆盖 paintComponent
.
2) 不要忘记兑现油漆链并调用super.XXX
覆盖的实现 paintComponent(Graphics g)
(或针对该事实的任何覆盖方法)除非有意将其排除在外。即
class MyPanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
//do drawings here
}
}
3) 如果绘制paintComponent
通常需要覆盖 getPreferredSize()
并返回 Dimension
符合 JPanel
的内容/图纸的 s ,即:
class MyPanel extends JPanel {
@Override
public Dimension getPreferredSize() {
return new Dimension(300,300);
}
}
3) 查看 Swing Timer
而不是 Thread.sleep(..)
作为sleep
将阻塞 GUI 线程并使其看起来被卡住。即
Timer t = new Timer(10, new AbstractAction() {
int count = 20;
@Override
public void actionPerformed(ActionEvent ae) {
if (count < 1000) {
//increment rectangles y position
//now repaint container so we can see changes in co-ordinates (unless you have a timer which repaints for you too)
count++;
} else {//counter is at 1000 stop the timer
((Timer) ae.getSource()).stop();
}
}
});
t.start();
4) Swing 计时器的替代方案(因为我现在看到您只是将 Rectangle
不是 Swing 组件)移动为 TimerTask
,只要不会从其 run()
中创建/操作 Swing 组件,就可以使用它。方法(因为 TimerTask
不像 Swing Timer 那样在 EDT 上运行)。备注revalidate()
和 repaint()
是线程安全的,因此可以在 TimerTask
中使用.
上面的优点是保留了 EDT 的不必要代码(即通过更改坐标移动 AWT 矩形)即
final TimerTask tt = new TimerTask() {
@Override
public void run() {
if (count < 1000) {
//increment rectangles y position
//now repaint container so we can see changes in co-ordinates (unless you have a timer which repaints for you too)
count++;
} else {//counter is at 1000 stop the timer
cancel();
}
}
};
new Timer().scheduleAtFixedRate(tt, 0, 10);//start in 0milis and call run every 10 milis
关于java - 线程绘制方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14072940/