为什么paint()被调用2次? 本帖最后由 Kende0120 于 2011-10-11 02:19:21 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 教材说对啦,启动程序时(第一次显示jpanel)调用了一次每一次重画时也会被调用,比如,你把拉放窗口,或者最小化再最大化 这时也会调用repaint 第一步建立一个文件文件名:Demo9_1.java文件内容: 复制楼主的第二步,同一目录下建立一个文件文件名:Demo9_1.bat文件内容:javac Demo9_1.javajava Demo9_1然后双击它 [Quote=引用 3 楼 k3108001263 的回复:]引用 2 楼 kende0120 的回复:你说的分马牛不相及啊我又不是不知道编译和启动程序! 是打印出2次的。paint()下也有这一句,System.out.println("paint() is called !");所以我才知道是被调用2次的。 你的类作为子类继承JPanel重写了paint方法 父类调用paint方法就是调用你重写后的方法 --------------->>发生多态现象所以会打印出一句 paint() is called ! ,而不是两句 打印出一句 paint() is called ! , 意味着调用一次楼主你哪里概念混乱啦 最初你说调用两次,我一开始以为你的程序会输出两句,paint() is called !现在看来是你自己 编造的调用两次 看到这个东西http://javapub.iteye.com/blog/763970,不过好像没有效果,楼主试试 我没有概念混乱,我的问题很简单,以上代码 正常的运行结果是 打印 paint() is called ! 1次,而我的电脑上运行结果是 打印 paint() is called ! 2次,也就意味着我重载的paint方法被调用了2次,我不知道原因在哪来。我在其他电脑上运行过了,结果正常,只打印了一次,估计不是程序的问题,和我电脑的运行环境有关。 真麻烦! 使用万能方法试试:////////////////////////////////////////////////////////////////////////////////////////////////下载安装对应版本的JDK:64位操作系统:http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-windows-x64.exe32位操作系统:http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-windows-i586.exe////////////////////////////////////////////////////////////////////////////////////////////////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;////////////////////////////////////////////////////////////////////////////////////////////////// 说说是在什么系统、java版本下遇到的问题 系统 xp sp3java 1.6.0_26有何良策? 我运行也是打印出2句paint() is called ! Swing的JComponent以及其子类的绘制默认是使用了双缓冲的,例如JPanel Debag` 线程问题 Swing VS main 线程 public synchronized void paint(Graphics g) 希望对你有用 \(^o^)/~ 试试吧 我还没试呢 o(╯□╰)o 加上 synchronized 也没变 你的解释有点给力,可是仍然存在疑问,1,awt的frame 我也用过,结果也是打印2次2,既然双缓冲功能是java本身带的,那就应该和电脑没关系的, 都是自动的,也不存在双缓冲设置问题。 电脑不同运行结果不同,这是最不能理解的。不花时间想这个问题了,反正程序不出问题就行了。谢谢你的解答! 囧 刚才试了下竟然不是 真丢人`` 好好看了下代码 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 补充 JFrame 为 false 即 isVisible 为 false 就不会发生 绘画 (因为绘画了 也无法显示) 所以 JPanel 高层的 画布 会等待 底层的 JFrame容器 的 setvisible (true) 的发生 向28楼学习,原来swing有这么好玩的东西 我试过了,你的方法可以解决paint被调2次的问题,而且也让我学习了 主线程和swing线程非常感谢!辛苦了,o(∩_∩)o...看来你真是个喜欢深入研究的人,以后有机会还希望能多多指教。 对数组进行降序排列的API有哪些 ???菜鸟的困惑。 紧急求助:可否不通过WEB服务器,实现http方式的在线接收数据流??? 有没这样一个集合?? 高手帮忙了,急啊。我水平太臭,两天解决不了。帮我解决了就散100分 [求助]请问英文资料的找法问题 请问TIJ第三版第三章练习6是什么意思? 刷新Jtable 急!100分!用applet做一个画流程图的界面,有几个疑问?立马给分! 初学者请求帮忙————很菜的问题。 DataOutputStream 问题? 各位大大,为啥我画的圆有毛边,加了双缓冲还是看见一闪一闪的?
第一步建立一个文件
文件名:Demo9_1.java
文件内容: 复制楼主的
第二步,同一目录下建立一个文件
文件名:Demo9_1.bat
文件内容:
javac Demo9_1.java
java Demo9_1
然后双击它
引用 2 楼 kende0120 的回复:你说的分马牛不相及啊
我又不是不知道编译和启动程序!
System.out.println("paint() is called !");
所以我才知道是被调用2次的。
你的类作为子类继承JPanel重写了paint方法
父类调用paint方法就是调用你重写后的方法 --------------->>发生多态现象
所以会打印出一句 paint() is called ! ,而不是两句
最初你说调用两次,我一开始以为你的程序会输出两句,paint() is called !
现在看来是你自己 编造的调用两次
我的问题很简单,以上代码 正常的运行结果是 打印 paint() is called ! 1次,
而我的电脑上运行结果是 打印 paint() is called ! 2次,也就意味着
我重载的paint方法被调用了2次,我不知道原因在哪来。我在其他电脑上运行过了,结果正常,只打印了一次,
估计不是程序的问题,和我电脑的运行环境有关。 真麻烦!
下载安装对应版本的JDK:
64位操作系统:http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-windows-x64.exe
32位操作系统:http://download.oracle.com/otn-pub/java/jdk/7/jdk-7-windows-i586.exe
////////////////////////////////////////////////////////////////////////////////////////////////
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;
//////////////////////////////////////////////////////////////////////////////////////////////////
java 1.6.0_26有何良策?
希望对你有用 \(^o^)/~ 试试吧 我还没试呢 o(╯□╰)o
2,既然双缓冲功能是java本身带的,那就应该和电脑没关系的,
都是自动的,也不存在双缓冲设置问题。
电脑不同运行结果不同,这是最不能理解的。不花时间想这个问题了,反正程序不出问题就行了。
谢谢你的解答!
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
而且也让我学习了 主线程和swing线程非常感谢!辛苦了,o(∩_∩)o...
看来你真是个喜欢深入研究的人,以后有机会还希望能多多指教。