当前位置: 代码迷 >> J2SE >> 为什么paint()被调用2次?该怎么解决
  详细解决方案

为什么paint()被调用2次?该怎么解决

热度:96   发布时间:2016-04-24 12:18:33.0
为什么paint()被调用2次?
以下代码是在jpanel上画图。启动窗口的时候,教程上paint只被调用一次,
我的程序和教程一模一样,却被调用2次,难道是我的电脑设置问题?
哪位朋友可以看出bug ?

Java code
import javax.swing.*;import java.awt.*;public class Demo9_1 extends JFrame {    MyPanel mp = null;    public static void main(String[] args) {        Demo9_1 demo9_1 = new Demo9_1();    }    public Demo9_1() {        mp = new MyPanel();        this.add(mp);        // =========================================        this.setSize(400, 300);        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        this.setVisible(true);                // =========================================    }}class MyPanel extends JPanel {        public void paint(Graphics g) {        super.paint(g);                System.out.println("paint() is called !");                g.setColor(Color.red);        g.fillRect(70, 10, 40, 60);        g.setColor(Color.blue);        g.fillRect(70, 90, 40, 60);            }}



------解决方案--------------------
使用万能方法试试:
Java code
////////////////////////////////////////////////////////////////////////////////////////////////下载安装对应版本的JDK:64位操作系统:[url=http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-windows-x64.exe][/url]32位操作系统:[url=http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-windows-i586.exe][/url]////////////////////////////////////////////////////////////////////////////////////////////////JAVA_HOME设置(每个人都不一样,确保它的子目录有:bin,demo,include,jre,lib)jdk目录的具体路径,比如   ;D:\Program Files\Java\jdk1.7.0;ClassPath设置(初学者直接复制到环境变量的最前端,高手请按自己的想法做):;%JAVA_HOME%\bin;.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\jre\lib\rt.jar;Path设置(直接复制到环境变量的最前端):;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;.;%JAVA_HOME%\..\jre7\bin;%JAVA_HOME%\..\jre6\bin;%JAVA_HOME%\..\jre5\bin;//////////////////////////////////////////////////////////////////////////////////////////////////
------解决方案--------------------
囧 刚才试了下竟然不是 真丢人`` 好好看了下代码 
this.add(mp); 你要是 放到 最后 就不会出现 这种情况``
为啥 我猜是这样滴
JFrame 默认是不会生成 Graphics的 除非是 setVisible(true); 或者 用GraphicsDivice 生成 全屏模式 会返回Graphics ````
但是 你的 JPanel 的默认 setVisible(true); 是生成 Graphics对象的;
好了 直奔主题

AWT的 EventQueue(Queue -- >队列!!) 的任务(也就是线程) 它是负责 绘画的 (当然也负责鼠标事件云云的东西) 当 先add(); AWT的线程 并不会马上调用 因为程序还没运行结束 并不知道 JFrame 是否为ture 这时 JPanel 的 paint 进入队列 等待 JFrame 的 setVisible (true) 发生` 也就是说 JFrame 为真的时候 JFrame 的 paint 也加入队列 并开始执行`` (队列么 想象先进先出 依次调用`现实JFrame 的 在 JPanel 明白了吧!) --> 看源码 没看懂 功力不够 所以 做了3个实验 `` 自己看输出结果吧: 我相信这个 说法 会让你信服的 
(--------):
public Demo9_1() {

mp = new MyPanel();

this.add(mp);
// for(int i =1 ; i <1000; i++){
// System.out.println(i);
// }
this.setSize(400, 300);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
// for(int i =1 ; i < 1000 ; i ++){
// System.out.println("i");
// }

}

注释 : 依次去掉注释 并观察 paint() 中的 paintln() 出现的位置 一定要记住 main VS AWT 线程 \(^o^)/~
希望对你有用 呼`` 累之```o(╯□╰)o
  相关解决方案