现在已经实现的功能大体分为两种:一,以鼠标拖动轨迹绘图;二,以固定图形绘图(包括直线,长方形,椭圆等)。
第一种功能我是以getGraphics方法写的,第二种功能用paint方法。利用了双缓冲。总的外在表现问题是:用一方法绘图时当窗口被遮挡或最小化恢复后,图形消失,在继续拖动鼠标时才出现之前的图形。(鼠标绘图的drawLine方法写在mouseDragged方法中,所以继续拖动,可以实现读取缓存中的图形。)这里的问题是如何才能使窗口被遮挡和窗口重新恢复之间的时间里图形不会消失(我尝试在WindowEvent中窗口最小化恢复方法里写入读取缓存图形的方法,结果没有效果);
用二方法时,当鼠标拖动后,之前画的图形消失(draw方法也是写在mouseDragged中,画特定图形时用到了repaint方法,这样以保证按住鼠标拖动时让图形变化,而不是画很多图形)。这里其实我也知道用到repaint就有一个清除的过程,我尝试在mousepressed,mousereless方法里读取缓存图象,但都得不到稳定的效果。可是WINDOWS画图程序里就是用同样的表现方式绘图,却不会有消失的过程。这里的问题就是如何做到WINDOWS画图程序中画多个特定图形但都不会消失的效果。之后还有个小问题,就是我让绘图区域继承JPanel类时,设定了背景色为白,但当用鼠标拖动绘图时背景色变成了菜单色(铅色),换成继承Panel类时却一切正常,这是什么原因呢~写了一大堆,希望高手们不厌其烦,帮助帮助小弟~~万分感谢!

解决方案 »

  1.   

    把每个图标的对象定义成一个类,然后每画一个图后,就生成这个类的对象,保存这些对象,当Panel刷新的时候,这些对象都绘制一遍.
      

  2.   

    应该在paint()或者paintComponent()方法中绘制,因为窗口被遮挡或最小化恢复后,会调用repaint(),repaint()调用的paint()方法,paint()再调用paintComponent()方法,所以写在其他地方的绘制代码根本不会被执行。所以绘制应该在paint()或者paintComponent()方法中进行,保证重绘不会消失你的劳动成果。
      

  3.   


    今天请教了高手,用类似2楼高人的办法,我重新改了下。也就是在paint()方法中加了一个读取缓冲区,然后实现了图形不消失。但是这里面仍然有一些问题:
    如果直接在paint()中用绘图方法向缓存中画图,那按住鼠标拖动画线时就会出现无数条直线(出现从点击点到鼠标轨迹点之间的所有直线),也就是说想画特定图形必须要用到一个update清除方法。这样如果还是先在缓冲区绘图,那缓冲区不是会被清空吗,是否有其他方法先在缓冲区中绘图实现画特定图形呢
    如果在paint()中直接象Panel中画图,然后在mouseDragged方法中写入缓冲区,到是基本实现了WINDOWS画图程序的功能,唯一的缺点是画特定图形的时候会闪烁。这就是不断update的结果。直至现在没找到合适办法解决,再次期待高手!
      

  4.   

    不用缓冲,直接重写JPANEL类的paint方法就可以了。    public void paint(Graphics g){
    super.paint(g);
    g.drawRect(50,50,20,20);
        }
      

  5.   

    画的东西可以放在一个其他容器里,比如Vector里面。
    然后
    public void paint(Graphics g){ 
    super.paint(g); 
    for(int i = 0 ; i < vector.size();i++)
    draw(g,vector.get(i));
    }再写个draw方法用来实现画一个具体的东西。
      

  6.   


    再补充下,鼠标画东西事件是:
    vector.add();
    this.repaint();
      

  7.   


    也许有点误会或者我没理解~还请多指点~
    就是说,画特定图形的时候是点击点和鼠标拖动点之间不断的绘图,但在鼠标放开前是不断的清空的,所以,只有松开前的最后一个图形有效。如果不用缓冲,直接重写paint方法,那在画第2个图形的时候,第一个不也会被update掉吗;如果不用update或者重写使清除无效,那么画特定图形的时候拖动鼠标就出现无数个图形了
      

  8.   


    双缓冲就是用到的存储区域啊,只是开始什么时候取的问题没搞清楚。
    现在问题就是第二种功能的绘图方法直接画在Panel上会因为清除而闪烁;但画到缓冲区的合适方法我还没找到,因为第二种功能涉及到一个必须清除的过程。