本帖最后由 yaojianquansb 于 2010-07-30 15:45:24 编辑

解决方案 »

  1.   

    JPanel 详述:            从JComponent类继承的Swing组件包含paintComponent方法,这个方法有助于Swing组件在Swing GUI上下文中正确地绘制。当用定制的JPanel作为专用的绘图区域时,子类应当覆盖超类的paintComponent方法,并且将调用超类的paintComponent方法的语句作为被覆盖的方法体内的第一条语句。这样就能保证按正确地次序绘图,并且确保完整地保留Swing的绘图机制。这种机制的一个重要特点是JComponent的子类可以通过设置setOpaque方法(参数false表明组件是透明的)支持透明。为了正确绘制组件,程序必须判断组件是否透明。超类的paintComponent方法负责执行检查。当程序在组件是透明的情况下绘制组件时,paintComponent方法不清除组件的背景色。当组件不透明时,paintComponent方法在继续绘制前清除背景色。如果不调用超类的paintComponent方法,不透明GUI组件便不能再用户界面上正确显示。同样,如果超类的paintComponent方法在定制绘制语句执行后才调用,结果将被擦除。
      

  2.   

    没看到谁调用paintComponent方法的。
      

  3.   

    paintComponent是回调方法,组件在重绘的时候就会调用,本来这个方法就不是给程序员调用的,我们经常覆盖这个方法只是用来告诉组件,应该按照什么方式重绘,而不是我们去调用这个方法,你可以在组件上调用repaint方法,其实内部调用了这个方法,具体要看源码了
      

  4.   

    建议看下源码java.swing.JComponent的 paintComponent和java.swing.plaf.ComponentUI的update、paint这几方法
      

  5.   

    个人认为:当系统认为需要重绘是自动调用.
    楼主可以不用考虑这么深。
    你只要知道你是重写了这个方法而系统会自动调用。这个方法是重绘所有组件的方法。
    JComponent 源码如下:    protected void paintComponent(Graphics g) {
            if (ui != null) {
                Graphics scratchGraphics = (g == null) ? null : g.create();
                try {
                    ui.update(scratchGraphics, this);
                }
                finally {
                    scratchGraphics.dispose();
                }
            }
        }
     public void update(Graphics g) {
            paint(g);
        }可以看出调用顺序paintComponent-->update-->paint
      

  6.   

    public void update(Graphics g, JComponent c)
      

  7.   

    系统自动调用。
    就像awt上的Canvas中的repaint->update->paint一样!
      

  8.   

    public void run() {
    try {
        pumpEvents(new Conditional() {
    public boolean evaluate() {
        return true;
    }
        });     
    } finally {
        /*
         * This synchronized block is to secure that the event dispatch 
         * thread won't die in the middle of posting a new event to the
         * associated event queue. It is important because we notify
         * that the event dispatch thread is busy after posting a new event
         * to its queue, so the EventQueue.dispatchThread reference must
         * be valid at that point.
         */
        synchronized (theQueue) {
                    if (theQueue.getDispatchThread() == this) {
                        theQueue.detachDispatchThread();
                    }
                    /*
                     * Event dispatch thread dies in case of an uncaught exception. 
                     * A new event dispatch thread for this queue will be started
                     * only if a new event is posted to it. In case if no more
                     * events are posted after this thread died all events that 
                     * currently are in the queue will never be dispatched.
                     */
                    /*
                     * Fix for 4648733. Check both the associated java event
                     * queue and the PostEventQueue.
                     */
                    if (theQueue.peekEvent() != null || 
                        !SunToolkit.isPostEventQueueEmpty()) { 
                        theQueue.initDispatchThread();
                    }
    AWTAutoShutdown.getInstance().notifyThreadFree(this);
        }
    }
        }