Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 405|回复: 0

[Java基础知识]手把手教您如何编写一个动画Applet实例

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-1 07:54:29 | 显示全部楼层 |阅读模式
    Applet是在浏览器中运行的小程序,java也是从Applet开始风靡世界的。通过编写这个Applet,我们可以学习到如下知识:

    1、Applet及JApplet中的主要接口

    2、图像的装载及MediaTracker的使用

    3、线程的使用及多个线程直接的通讯

    4、Thread.join()方法的使用

    5、volatile关键字的使用

    动画的主要部分是一个Applet,从codebase中读取一组图片文件,然后每隔1秒轮换显示一张。代码如下:
      
       
       
       

       
      

       



      
       
       
         
       
    1.       
    2.         import javax.swing.JApplet;
    3. import java.awt.Graphics;
    4. import java.awt.Image;
    5. import java.awt.MediaTracker;
    6. public class Animate extends JApplet
    7. {
    8.     //图片数量
    9.     private static final int NUM_OF_PIC = 4;
    10.      
    11.     int count;
    12.     Image pics[];
    13.     TimerThread timer;
    14.      
    15.     public void init()
    16.         {
    17.         count = 1;
    18.         pics = new Image[NUM_OF_PIC];
    19.         MediaTracker tracker =
    20.                 new MediaTracker(this);
    21.         for(int i = 0; i<NUM_OF_PIC; i++)
    22.                 {
    23.     //将图片按照0,1,...,NUM_OF_PIC -1,
    24.         放置在目录中,格式为.jpg
    25.             pics[i] = getImage(getCodeBase(),
    26.                 new Integer(i).toString()+".jpg");
    27.             tracker.addImage(pics[i], 0);
    28.         }
    29.         tracker.checkAll(true);
    30.          
    31.     }
    32.      
    33.     public void start()
    34.         {
    35.             timer = new TimerThread(this, 1000);
    36.             timer.start();
    37.     }
    38.      
    39.     public void stop()
    40.         {
    41.         timer.shouldRun = false;
    42.         try {
    43.             timer.join();
    44.                         //等待timer线程退出
    45.         } catch (InterruptedException e)
    46.                 {
    47.                 };
    48.     }
    49.      
    50.     public void paint(Graphics g)
    51.         {
    52.         g.drawImage(pics[count++], 0, 0, null);
    53.         if(count == NUM_OF_PIC) count = 0;
    54.     }
    55.      
    56. }
    57.       
    复制代码

         
       
       
      


    动画的控制由一个专门的线程TimerThread进行处理。



      
       
       
         
       
    1.       
    2.         import java.awt.Component;
    3. public class TimerThread extends Thread
    4. {
    5.     Component comp;
    6.     int timediff;
    7.      
    8.     //    shouldRun声明为volatile
    9.     volatile boolean shouldRun;
    10.      
    11.     public TimerThread
    12.         (Component comp, int timediff)
    13.         {
    14.         super("TimerThread
    15.                 (" + timediff + " millseconds");
    16.         this.comp = comp;
    17.         this.timediff = timediff;
    18.         shouldRun = true;
    19.     }
    20.      
    21.     public void run()
    22.         {
    23.         while(shouldRun)
    24.                 {
    25.             try
    26.                         {
    27.                 comp.repaint();
    28.                 sleep(timediff);
    29.             } catch (Exception e)
    30.                         {
    31.                         }
    32.         }
    33.     }
    34. }
    35.       
    复制代码

         
       
       
      


    MediaTracker的使用

    在Applet中获取一个图像文件,可以调用Applet的getImage()方法。但是getImage方法会在调用后马上返回,如果此时马上使用getImage获取的Image对象,而这时Image对象并没有真正装载或者装载完成。

    所以,我们在使用图像文件时,使用java.awt包中的MediaTracker跟踪一个Image对象的装载,可以保证所有图片都加载完毕。使用MediaTracker需要如下三个步骤:

    1、实例化一个MediaTracker,注意要将显示图片的Component对象作为参数传入。



      
       
       
         
       
    1.       
    2.         MediaTracker tracker = new MediaTracker(this);
    3.       
    复制代码

         
       
       
      


    2、将要装载的Image对象加入MediaTracker



      
       
       
         
       
    1.       
    2.         pics[i] = getImage(getCodeBase(),
    3.   new Integer(i).toString()+".jpg");
    4. tracker.addImage(pics[i], 0);
    5.       
    复制代码

         
       
       
      


    3、调用MediaTracker的checkAll()方法,等待装载过程的结束。



      
       
       
         
       
    1.       
    2.         tracker.checkAll(true);
    3.       
    复制代码

         
       
       
      


    Thread.join()的使用

    我们在Animate的stop方法中调用timer的join()方法,将timer线程连接(join)到当前线程,当前线程会一致会等待timer线程运行结束后,timer.join()方法才会返回。

    如果当前线程在等待timer返回的过程中,被其它线程中断了,那么当前线程会抛出InterruptedException。如果不使用Thread的join方法,那么只能通过轮询timer线程的状态进行判断了:



      
       
       
         
       
    1.       
    2.         while (timer.isAlive())
    3. {
    4.       try
    5.           {
    6.         Thread.sleep(50);
    7.            }
    8.                    catch (InterruptedException e)
    9.                    {
    10.                    }
    11.          }
    12.       
    复制代码

         
       
       
      


    显然这种办法和使用join方法相比,会浪费cpu资源,同时也会浪费一些等待时间,因为当前线程每隔一段时间去查询timer线程是否还存活,可能在timer线程已经结束了,但是当前线程还是要等待一段时间才能去监测它。

    关于volatile

    我们知道,在Java中设置变量值的操作,除了long和double类型的变量外都是原子操作,也就是说,对于变量值的简单读写操作没有必要进行同步。这在JVM 1.2之前,Java的内存模型实现总是从主存读取变量,是不需要进行特别的注意的。

    而随着JVM的成熟和优化,现在在多线程环境下volatile关键字的使用变得非常重要。在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。

    这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值的拷贝,造成数据的不一致。

    要解决这个问题,只需要像在本程序中的这样,把该变量声明为volatile(不稳定的)即可,这就指示JVM,这个变量是不稳定的,每次使用它都到主存中进行读取。一般说来,多任务环境下各任务间共享的标志都应该加volatile修饰。
      

      
      
       
       

         
       

         
       
      


      



                            function TempSave(ElementID)
                            {
                                    CommentsPersistDiv.setAttribute("CommentContent",document.getElementById(ElementID).value);
                                    CommentsPersistDiv.save("CommentXMLStore");
                            }
                            function Restore(ElementID)
                            {
                                    CommentsPersistDiv.load("CommentXMLStore");
                                    document.getElementById(ElementID).value=CommentsPersistDiv.getAttribute("CommentContent");
                            }
                   
                      











    源码下载:http://file.javaxxz.com/2014/10/1/075429422.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-6 10:10 , Processed in 0.511098 second(s), 48 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表