我的目标是绘制矩形并使用Observer模式从左至右平滑地移动它。带观察者模式的Java Swing多线程管理
我有一个Model类,它是Observable放置矩形的坐标,Display类是Observer,每次模型中的坐标改变时执行重绘。
模型中的坐标变化是在SwingWorker中的while循环中进行的:在每次迭代中,我将x坐标增加1,然后休眠100 ms,然后通知观察者(显示器)哪个任务是执行重绘。正如你所看到的那样,在EDT上调用repaint()方法就像它被建议做的那样。
问题是移动大约一秒后不平滑,重绘频率改变,看起来矩形越来越少重新绘制。
这里是模型类:
import java.util.Observable;
import java.awt.EventQueue;
import javax.swing.SwingWorker;
public class Model extends Observable{
int xCoordinate;
Model(Display d){
SwingWorker<Void,Void> sw = new SwingWorker<Void,Void>(){
@Override
protected Void doInBackground() {
while(xCoordinate<600){
xCoordinate ++;
try {
Thread.sleep(100);
} catch (InterruptedException ex) {}
setChanged();
notifyObservers(xCoordinate);
}
return null;
}
};
addObserver(d);
sw.execute();
}
public static void main(String[] a){
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
Display d = new Display();
Model m = new Model(d);
d.model = m;
}
});
}
}
这里是Display类:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Display extends JFrame implements Observer{
Model model;
int xCoordinate;
Display(){
getContentPane().add(new JPanel(){
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.RED);
g.fillRect(xCoordinate, 1, 50, 50);
}
});
setSize(600, 600);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
/* arg is the updated xCoordinate*/
public void update(Observable o, Object arg) {
xCoordinate = (Integer)arg;
EventQueue.invokeLater(new Runnable(){
@Override
public void run() {
repaint();
}
});
}
}
我尝试过其他方法,例如在利用显示计时器,但没有奏效无论是。 SwingWorker可能在这里没有用,因为在SwingWorker线程上进行的计算很容易(增加1),但是我将需要它来执行我打算在我的项目(池游戏)上进行的繁重计算。
我也尝试通过查看两次重新绘制之间的时间(在Display中)和两次递增之间的时间(模型中)来调试,并且它的预期时间约为100 ms。
在此先感谢
你可以改变的睡眠时间?尝试10毫秒,它会移动更顺利。 – ahoxha
那么它仍然不流畅(至少在我的电脑上)。我试了10和500毫秒。 – Alsvartr
我尝试了一个使用'javax.swing.Timer'的例子,但将延迟设置为100毫秒,它不能平稳移动。以下是示例:http://www.java2s.com/Tutorial/Java/0240__Swing/Timerbasedanimation.htm。 – ahoxha