在Java Applet中连续绘制图像

时间:2014-08-17 07:01:02

标签: java animation applet awt event-dispatch-thread

我试图在Applet上绘制大约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的图像,我希望它们在我的Applet窗口上,并且在显示图像后1秒延迟应该存在。但这种情况并非如此。请帮忙

3 个答案:

答案 0 :(得分:2)

sleep将冻结EDT(事件调度线程)。由于Swing是单线程框架,因此从EDT 上下文调用paint后,阻止(如睡眠)的任何内容都会阻止EDT运行。不要使用睡眠,而是使用Timer

另一方面,catch 例外并且没有处理它是不好的做法。这将隐藏代码中可能出现的严重意外事件,至少打印错误消息。

答案 1 :(得分:1)

使用Thread.sleep(),因为它会冻结您的Swing应用程序。

相反,您应该使用javax.swing.Timer

有关更多信息和示例,请参阅Java教程How to Use Swing TimersLesson: Concurrency in Swing

答案 2 :(得分:0)

你应该做什么

  1. 不要直接在applet上绘图。在像JPanel这样的单独面板上绘制并将其添加到applet。
  2. 在阻止EDT时不要调用sleep()。所有Swing组件都在EDT上绘制,因此如果它被阻挡,则会导致问题。
  3. 有人也尝试使用单独的线程,但它不是一个好的选择,因为线程会休眠一段时间,然后调用repaint()mis。最好使用javax.swing.Timer,它会在一段时间后触发事件。
  4. 试试此代码

    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();
        }
    }
    

    当我从Timer的ActionListener中读取文件中的图像时,我的代码仍然存在缺点。对于初学者来说现在可以了,但是我建议你使用SwingWorker,它会在applet启动之前预先加载图像。我将在稍后提供此升级