import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;import javax.swing.JFrame;
import javax.swing.JPanel;
public class Draw extends JFrame 
{
Graphics g;
public Draw()
{
super("Draw");
setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setPreferredSize(new Dimension(300,400));
pack();
setVisible(true);
g = getGraphics();
}
/* public void paint(Graphics g)
{
g.drawRect(10, 30, 30, 40);
}*/
public void shows()
{
if(null != g)
{
g.drawRect(10, 30, 30, 40);
}
g.dispose();
}
public static void main(String[] args)
{
Draw test = new Draw();
test.shows();
}
}
这段简单的代码,如果把shows函数注释掉,并且在主函数里不调用shows那么用paint方法来画这个矩形是没问题的
但是我把paint方法注释掉之后,采用shows方法,然后在主函数里面调用shows就出现了奇怪的现象:这个矩形闪了一下就不见了
请问是怎么回事呢?

解决方案 »

  1.   

    个人感觉是g.dispose();的问题,因为 Graphics 是一个抽象类,所以应用程序不能直接调用此构造方法。图形上下文从其他图形上下文获取,或者通过在组件上调用 getGraphics 来创建。 当你调用当前JFrame 对象的getGraphics()方法获取到g尔后又调用g.dispose();将对象销毁,这样g应该就是null了。
      

  2.   

    不行的哦,不写dispose也是不行的哦
      

  3.   

    没有放到事件派发线程中执行,修改下就好了public class Draw extends JFrame 
    {
        static Graphics g;
        public Draw()
        {
            super("Draw");
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            this.setPreferredSize(new Dimension(300,400));        
            pack();
            setVisible(true);
            g = getGraphics();
        }    public static void shows()
        {
            if(null != g)
            {
             g.drawRect(10, 30, 30, 40);
            }
            g.dispose();
        }
        public static void main(String[] args)
        {
            Draw test = new Draw();
            SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    Draw.shows();
    }        
            });      
        }
    }
      

  4.   

    同意楼上观点。对Swing来说,界面绘制等操作都应该在事件派发线程中运行
      

  5.   

    不认同楼上的观点, paint() 是java内部调用,你可以加断点调一下,并非执行一次,也就是说,java内部可能有好几个地方要调用paint(),你简单的把paint()换为shows()调用一次,显然是不行的!另外,我按照楼上的方法调试了下,并不能显示出来,我的理解 SwingUtilities.invokeLater()是多线程异步刷新用的,
      

  6.   

    不知道是不是jdk的版本问题,我的jdk1.6.0_07,通过show画出的矩形可以正常现实,另shows()同paint()两个函数之间没有什么联系
      

  7.   

    frame里面包含有默认的root pane, 当你不复写paint方法的时候,他会绘制子组件,所以你会看到一闪而过的情况, 画完了矩形就去画子组件了,你画的就被覆盖了
    还有就是最好不要用getGraphics()方法得到的graphic去绘制东西,所有的绘制都应该在paint方法传进来的那个graphic上绘,