最近做地图加载,需要在JPanel上绘制图片,但图片较多,只有用一个大的JPanel(开始一张图片用了一个Jpanel,但软件运行到一定程度后内存溢出,因为创建了太多JPanel),一次绘制一张,在JPanel的特定位置,图片可拼接成地图,怎么可以只调用一次new还实现绘制多个不同的图片?怎样把绘制过图片的地方内存释放?

解决方案 »

  1.   

    你这样来一个层就new 一个panel,内存肯定会爆。
    你可以每次绘制成功之后把当前panel的图片保存下来,然后把保存下来的图片画到主panel上。
    这个过程总共是2个panel,但是会额外增加操作,截图,保存文件,读文件等
      

  2.   

    你如果是要绘制大面积图形的话,基本上不能全部都预先绘制,只能是按需绘制,也就是判断滚动条滚到什么位置了,就把对应的图块绘制上去,形成当前位置所需要显示的内容。你用过 map.baidu.com 之类的在线地图么?用鼠标狂拖动下,就会看到边缘的图块在不断的加载进来。你要做的就是类似这种效果。当然,为了拖动更加平滑之类的考虑,你生成的图形需要比窗口可视面积要大一些,这样前面用户边拖拽,后面可以同步用另一个图形工作区来更新所需的图块,然后再前后图形工作区切换下。
      

  3.   

    关于2楼的想法已经实现,我的问题就是就是怎样不通过new(或者内存不会溢出),在一个面板上绘制较多图片(图片存在数据库中)??
      

  4.   

    正确的做饭是提供一个图片加载线程,每次成功加载之后repaint一下JPanel就可以啦
    而且所有图片应该都在一个JPanel上显示,位置要根据图片大小确定新图片的起始点位置
    偏移。
      

  5.   


    先用两个BufferImage作为两个工作区,面积要大于窗口可视面积,一个作为前景工作区、一个作为后台工作区。重载JPanel的paint函数,职能简单,就是根据伪进度条相对位移,将把前景工作区的内容直接draw到JPanel上即可。编写伪进度条的滚动事件,控制后台工作区(另外线程负责,不要占用GUI线程的工作时间)根据伪进度条的移动情况,重绘图形;绘制完毕后 前景 和 后台 工作区做切换。
    其实都不需要创建任何JPanel,你直接绘到窗体上也没问题。只不过需要两个滚动条。
      

  6.   


    先用两个BufferImage作为两个工作区,面积要大于窗口可视面积,一个作为前景工作区、一个作为后台工作区。重载JPanel的paint函数,职能简单,就是根据伪进度条相对位移,将把前景工作区的内容直接draw到JPanel上即可。编写伪进度条的滚动事件,控制后台工作区(另外线程负责,不要占用GUI线程的工作时间)根据伪进度条的移动情况,重绘图形;绘制完毕后 前景 和 后台 工作区做切换。
    其实都不需要创建任何JPanel,你直接绘到窗体上也没问题。只不过需要两个滚动条。我现在的想法测试了,又出了问题,就是每次只能绘制一张图片,下一次绘制的图片被上一次的覆盖,在网上看到了一篇关于双缓冲的博客,感觉我的问题能被解决,其实我的学长好像就是在用双缓冲来加载n张图片,可他就是什么也不说,由于地图需要拖动,所以JPanel还是要用的
      

  7.   

    绘图工作区就是用BufferImage来完成,长宽可以是窗口界面长宽的3倍。JPanel真的不重要,增加了你逻辑处理复杂度而已,拖动其实应该是你自己处理的;你见过Google或Baidu的地图,用了浏览器的滚动条来实现地图拖动么?相同位置重绘本来就应该被覆盖,否则岂不是乱了?我估计你是想拼接,但是位置没控制好,所以互相重叠了。
      

  8.   

    只是我绘制图片的方法,请指教class testppic extends JPanel
    {
    BufferedImage bi;
    Image i1;
    testppic(){
    try{

    bi=ImageIO.read(GetPic.in);
    setBounds(0,0,3500,4800);
    //设置面板大小
    }catch(Exception e){e.printStackTrace();}
    }  public void paint(Graphics g){
    //bi=ImageIO.read(GetPic.in);
    g.drawImage(bi,GetPic.x1,GetPic.y1,700,600,null);
    }
    每次绘制图片都new一次testppic,(测试时new了1000次,同一张图未出现内存溢出),GetPic.io是从数据库中读取的图片字节流,GetPic.x1,GetPic.y1是数据库中图片的坐标,每次只读取一张图,一次显示需要多个图片,需要多个new,但发现每次只要最后一张图显示了出来,求解惑
      

  9.   

    那你把testtppic做成单例的类,每次都重画拼接成么?
      

  10.   


    想要尽可能流畅,就要多级缓冲加预处理。这个程序至少可以分为四层来考虑:
    1、窗口层;2、工作区;3、内存区;4、数据库。如果窗口层需要展现的内容假定为 1 个单位;那么工作区就要尽量能围绕外面形成一圈(也就是8个单位);内存区就是围绕工作区再形成一圈(也就是16个单位以上)以及其它刚使用过的图块;数据库是全集了。这里说下内存区,也就是把数据库中的图片信息先读取出来成为 byte[],但是不要变成Image对象;根据原始图片压缩率情况,后者容量可能会大很多。
      

  11.   


    我觉得思路偏了,你想想:难道Windows系统,每次重绘都重新创建一次桌面对象?JPanel你如果想用,也只能当作一块黑板来用,不能每次去上课都去new一块新黑板,浪费资源和CPU。你应该是在黑板上不断的重绘。
      

  12.   

    楼主去找点书看吧,感觉对图形处理有点没入门,Java动画处理之类的,找你能看懂的就行。论坛解决理论体系的效率太低,只适合探讨具体问题而已。
      

  13.   

    多谢,才大二,碰java没半年,借书去