繁体   English   中英

在Java Applet中连续绘制图像

[英]Drawing images continuously in Java Applet

我试图在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秒延迟应该存在。 但这种情况并非如此。 请帮忙

sleep会冻结EDT(Event Dispatching Thread)。 由于Swing是单线程框架,所以阻止(如睡眠)的任何东西都会阻止EDT运行,因为从EDT上下文中调用了paint 不要使用睡眠,而是使用Timer

另一个注意事项, catch 异常而不处理异常是不好的做法。 这将隐藏代码中可能出现的严重意外事件,至少打印错误消息。

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

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

有关更多信息和示例,请参阅Java教程如何使用Swing TimersLesson:Swurrency中的并发

你应该做什么

  1. 不要直接在applet上绘制。 在像JPanel这样的单独面板上绘制并将其添加到applet。
  2. 不要在阻止EDT时调用sleep()。 所有Swing组件都在EDT上绘制,因此如果它被阻挡,则会导致问题。
  3. 有人也尝试使用单独的线程,但它不是一个好选项,因为线程会休眠一段时间,然后调用repaint()mis。 最好使用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();
    }
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM