我想在小程序得出100张图像。 当我这样做,我没能看到图像的过程太快了。 所以我加了休眠功能,这样我可以从一个图像到另一个给过渡之间的停顿。 但是,工作异常。 我没有看到任何图片,我认为睡眠是越来越一次又一次地叫。 请帮忙。
这里是我的代码:
public class Test extends Applet
{
public void init()
{
setSize(1000,1000);
}
public void make(Graphics g,int i)
{
}
public void paint(Graphics g)
{
int i=0;
for(i=0;i<100;i++)
{
if(i!=65)
{
Image img = getImage(getDocumentBase(), "abc"+i+".png");
g.drawImage(img, 0, 0, this);
try
{
Thread.sleep(1000);
}
catch(Exception exception)
{
}
}
}
}
}
现在你可以看到我有从0图像99,我希望他们在我的小程序窗口和图像显示1秒的延迟应该有后。 但这种情况并非如此。 请帮忙
sleep
将冻结EDT(事件指派线程)。 由于摆动是单线程框架,任何块(如睡眠),防止从EDT运行,因为paint
从EDT的上下文中调用。 不要使用休眠,使用Timer
来代替。
另外要注意,这是不好的做法, catch
一个例外 ,而不是处理它。 这将隐藏可能发生在你的代码,至少打印错误信息严重意想不到的事情。
不要使用Thread.sleep()
,因为它会冻结你的Swing应用程序。
相反,你应该使用javax.swing.Timer
。
请参阅Java教程如何使用Swing计时器和教训:并发摇摆的更多信息和示例。
你应该做的
- 不要直接在小程序绘制。 绘制像的JPanel一个单独的面板上,并把它添加到小程序。
- 不要调用睡眠(),因为它阻止EDT。 所有Swing组件都画在美国东部时间,所以如果被阻塞会引起问题。
- 有人还试图用一个单独的线程,但它太不是一个好的选择,因为线程睡眠时间,并呼吁然后重绘()错误。 这是更好地使用javax.swing.Timer中的其中一段时间后触发事件。
试试这个代码
public class Test extends JApplet {
int imgNo = 0;
BufferedImage bi;
JPanel p = new JPanel(){
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
if(bi != null)
g.drawImage(bi, 0, 0, null);
}
};
Timer t;
@Override
public void init() {
super.init();
setSize(400,400);
t = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try{
if(imgNo != 65)
bi = ImageIO.read(new File("abc"+i+".png"));
}catch(Exception e){
e.printStackTrace();
}
imgNo++;
p.repaint();
}
});
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
p.setOpaque(true);
p.setBackground(Color.white);
setContentPane(p);
}
});
}
@Override
public void start() {
super.start();
t.start();
}
@Override
public void stop() {
super.stop();
t.stop();
}
}
还有在我的代码的缺点,因为我在定时器的ActionListener的读取文件中的图像。 现在是OK的初学者,但我会建议你使用的SwingWorker将事先甚至小程序启动之前加载图像。 这个升级换代稍后我会提供