用Tracer跟踪,等图片数据全部装入的时候再显示。

解决方案 »

  1.   

    to eyes2near(eyes2near) 如何tracer对问题作以下补充
    在servlet中制作gif然后将做好的gif的URL传给applet
    在applet中更新,现在发现servlet执行完后url是传出来了,可是在server上生成的图像却是不完整的,所以applet显示出来的就只有一半的,不知高人有何意见
      

  2.   

    Here is an example: 
    -------------------------------------------------------------------------------- import java.applet.Applet;
     import java.awt.Color;
     import java.awt.Image;
     import java.awt.Graphics;
     import java.awt.MediaTracker; public class ImageBlaster extends Applet implements Runnable {
    MediaTracker tracker;
    Image bg;
    Image anim[] = new Image[5];
    int index;
    Thread animator; // Get the images for the background (id == 0) 
    // and the animation frames (id == 1) 
          // and add them to the MediaTracker
    public void init() {
        tracker = new MediaTracker(this);
        bg = getImage(getDocumentBase(), 
                      "images/background.gif");
        tracker.addImage(bg, 0);
        for (int i = 0; i <5; i++)="i++)" {="{" anim[i]="getImage(getDocumentBase()," "images/anim"=""images/anim"" +i+".gif");="+i+".gif");" tracker.addImage(anim[i],="tracker.addImage(anim[i]," 1);="1);" }="}" }="}" //="//" Start="Start" the="the" animation="animation" thread.="thread." public="public" void="void" start()="start()" {="{" animator="new" Thread(this);="Thread(this);" animator.start();="animator.start();" }="}" //="//" Stop="Stop" the="the" animation="animation" thread.="thread." public="public" void="void" stop()="stop()" {="{" animator="null;" }="}" //="//" Run="Run" the="the" animation="animation" thread.="thread." //="//" First="First" wait="wait" for="for" the="the" background="background" image="image" to="to" fully="fully" load="load" //="//" and="and" paint.="paint." Then="Then" wait="wait" for="for" all="all" of="of" the="the" animation="animation" //="//" frames="frames" to="to" finish="finish" loading.="loading." Finally,="Finally," loop="loop" and="and" //="//" increment="increment" the="the" animation="animation" frame="frame" index.="index." public="public" void="void" run()="run()" {="{" try="try" {="{" tracker.waitForID(0);="tracker.waitForID(0);" tracker.waitForID(1);="tracker.waitForID(1);" }="}" catch="catch" (InterruptedException="(InterruptedException" e)="e)" {="{" return;="return;" }="}" Thread="Thread" me="Thread.currentThread();" while="while" (animator="=" me)="me)" {="{" try="try" {="{" Thread.sleep(100);="Thread.sleep(100);" }="}" catch="catch" (InterruptedException="(InterruptedException" e)="e)" {="{" break;="break;" }="}" synchronized="synchronized" (this)="(this)" {="{" index++;="index++;" if="if" (index="(index">= anim.length) {
    index = 0;
        }
    }
    repaint();
        }
    } // The background image fills the frame so we 
    // don't need to clear the applet on repaints. 
          // Just call the paint method.
    public void update(Graphics g) {
        paint(g);
    } // Paint a large red rectangle if there are any errors 
    // loading the images.  Otherwise always paint the 
    // background so that it appears incrementally as it 
          // is loading.  Finally, only paint the current animation 
    // frame if all of the frames (id == 1) are done loading,
    // so that we don't get partial animations.
    public void paint(Graphics g) {
        if ((tracker.statusAll(false) & MediaTracker.ERRORED) != 0) {
    g.setColor(Color.red);
    g.fillRect(0, 0, size().width, size().height);
    return;
        }
        g.drawImage(bg, 0, 0, this);
        if (tracker.statusID(1, false) == MediaTracker.COMPLETE) {
    g.drawImage(anim[index], 10, 10, this);
        }
    }
     }
      

  3.   

    faint~~~,格式乱了。
    看这个吧http://java.sun.com/j2se/1.4.2/docs/api/java/awt/MediaTracker.html
      

  4.   

    to  eyes2near(eyes2near) 
    试了 MediaTracker
    ---------------------------------------------------------------------------------------
    public void paintComponent(Graphics g) {    if (this.tracker.checkID(1, true)) {
            g.drawImage(this.mapImageModified, 0, 0, this);
        }
        else {
            g.drawString("Loading picture. please hang on", 25, 50);
            System.out.println("Loading picture. please hang on");
        }
    }...mapImage = Toolkit.getDefaultToolkit().getImage(newMapImageUrl);
    tracker = new MediaTracker(this);
    tracker.addImage(mapImage, 1);
    tracker.waitForID(1);
    repaint();...-------------------------------------------------------------------------------------结果和原来一样,确实能看到"Loading picture. please hang on"这样的字
    可是显示出的图片就是有时会残缺不全。还试了 ImageObserver也是一样。感觉在图片显示前进行了是否下载完的确认,可是显示出来的就是奇怪。我快发疯了
      

  5.   

    执行到了else就说名数据没有加载全嘛。明显是你程序的问题,仔细去读一读sun上边的MediaTracer的例子。
      

  6.   

    在appletviewer中再怎么更新图片也不会有问题,可是将applet放在web上就会出现前述的问题。
      

  7.   

    to eyes2near(eyes2near) :
    照您的意思,程序应该是不会进入else的部分。我再仔细查一下程序。还有关于在appletviewer中没问题,在web上就会出问题。我仔细想了一想,在appletviewer中每连接一次Servlet,Session ID就会变一次,而再浏览器中多次执行Servlet也不会改变Session ID。而Servlet是根据session ID生成gif文件的URL。所以appletviewer中每次得到gif的URL是不同的,而浏览器中每次得到的gif的URL却是相同的。
      

  8.   

    to bbvoxkane14(兔也)可否详细说说。
      

  9.   

    试试
    this.getToolkit().createImage(this.getClass().getClassLoader().getResource("images/map.gif"));
      

  10.   

    现在还是想用字节流的方式,将gif文件读入bufferedImage中再显示,但不知道方法
      

  11.   

    to whycloud(云木) :
    双缓冲的原理其实就是实现在内存中绘制出image,然后再在前台画布上绘出图片,和楼主这个完全加载图片后再绘制是一个效果。楼主这个问题其实还是图片没有全部加载。
      

  12.   

    没碰到过这种情形,可能是你的程式有问题哦
    看看这个连接吧,不知是否对你有帮助http://tech.ccidnet.com/pub/article/c1078_a183275_p1.html
    友情up!  ^_^
      

  13.   

    先感谢各位给了我很多帮助,昨天总算使上述问题不再发生,但是不敢说解决了,因为只是没有再出现gif图片显示一般的现象。所以我将自己的做法写出来,与大家探讨。我的做法是,在servlet中将gif文件以流的方式传递到applet,applet再将读出的字节流转换成image用于显示。其中用了两种方法方法1
    -----------------------------------------------------------------------------------------
    public void receive() {
        InputStream in;
        BufferedInputStream imgStream;

        try {
            int byteReader;
            int cnt = 0;
            byte buf[] = new byte[MAX_IMAGE_SIZE];
            DataBufferByte dataBuffer = new DataBufferByte(buf, MAX_IMAGE_SIZE);

            in = urlExec.getConnection().getInputStream();
            imgStream = new BufferedInputStream(in);
      
            // BYTE单位读取
            while ((byteReader = imgStream.read()) != -1) {
                dataBuffer.setElem(cnt, byteReader);
       cnt = cnt + 1;
            }

            // 从Buffer生成ImageIcon
            image = new ImageIcon(Toolkit.getDefaultToolkit().createImage(dataBuffer.getData()));
            DebugPrint.printWithoutTitle("画像BYTE数 = " + cnt);    } catch (IOException e) {
    e.printStackTrace();
        }
    }方法2
    -----------------------------------------------------------------------------------------
    int count = 0;
    BufferedInputStream imgStream = new BufferedInputStream(in);byte buf[] = new byte[MAX_IMAGE_SIZE];
        
    try {
        count = imgStream.read(buf);
    } catch (IOException ieo) {
        System.err.println("Couldn't read stream from stream");
    }

    try {
        imgStream.close();
    } catch (IOException ieo) {
        System.err.println("Can't close file ");
    }

    image = new ImageIcon(Toolkit.getDefaultToolkit().createImage(buf));
    -----------------------------------------------------------------------------------------方法1的结果就是完整的将gif显示出来,感觉方法2会效率更高但会使得gif不论在浏览器中还是在appletviewer中的显示残缺。希望大家多提意见
      

  14.   

    请各位到以下帖子来领分 bbvoxkane14(兔也) ,eyes2near(eyes2near),thomas_20(执子之手,与子偕老),hhubon(河海笨笨) ,whycloud(云木) http://community.csdn.net/Expert/topic/3717/3717115.xml?temp=6.846255E-02
    http://community.csdn.net/Expert/topic/3715/3715431.xml?temp=.4448053