为什么paint()被调用2次?

Kende0120 2011-10-11 02:14:09
以下代码是在jpanel上画图。启动窗口的时候,教程上paint只被调用一次,
我的程序和教程一模一样,却被调用2次,难道是我的电脑设置问题?
哪位朋友可以看出bug ?


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);

}

}


...全文
710 30 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
privateTia 2011-10-15
  • 打赏
  • 举报
回复
补充 JFrame 为 false 即 isVisible 为 false 就不会发生 绘画 (因为绘画了 也无法显示) 所以 JPanel 高层的 画布 会等待 底层的 JFrame容器 的 setvisible (true) 的发生
privateTia 2011-10-15
  • 打赏
  • 举报
回复
囧 刚才试了下竟然不是 真丢人`` 好好看了下代码
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
Kende0120 2011-10-15
  • 打赏
  • 举报
回复
我试过了,你的方法可以解决paint被调2次的问题,
而且也让我学习了 主线程和swing线程

非常感谢!辛苦了,o(∩_∩)o...
看来你真是个喜欢深入研究的人,以后有机会还希望能多多指教。


[Quote=引用 27 楼 privatetia 的回复:]
囧 刚才试了下竟然不是 真丢人`` 好好看了下代码
this.add(mp); 你要是 放到 最后 就不会出现 这种情况``
为啥 我猜是这样滴
JFrame 默认是不会生成 Graphics的 除非是 setVisible(true); 或者 用GraphicsDivice 生成 全屏模式 会返回Graphics ````
但是 你的 JPanel 的默认 setVisible(t……
[/Quote]
打油的程序员 2011-10-15
  • 打赏
  • 举报
回复
向28楼学习,原来swing有这么好玩的东西
Kende0120 2011-10-14
  • 打赏
  • 举报
回复
是不是没人解决得了啊 。。。
Kende0120 2011-10-14
  • 打赏
  • 举报
回复
你的解释有点给力,可是仍然存在疑问,

1,awt的frame 我也用过,结果也是打印2次
2,既然双缓冲功能是java本身带的,那就应该和电脑没关系的,
都是自动的,也不存在双缓冲设置问题。
电脑不同运行结果不同,这是最不能理解的。

不花时间想这个问题了,反正程序不出问题就行了。
谢谢你的解答!


[Quote=引用 22 楼 x19881216 的回复:]
Swing的JComponent以及其子类的绘制默认是使用了双缓冲的,例如JPanel
[/Quote]
Kende0120 2011-10-14
  • 打赏
  • 举报
回复
加上 synchronized 也没变

[Quote=引用 24 楼 privatetia 的回复:]
Debag` 线程问题 Swing VS main 线程 public synchronized void paint(Graphics g)
希望对你有用 \(^o^)/~ 试试吧 我还没试呢 o(╯□╰)o
[/Quote]
privateTia 2011-10-14
  • 打赏
  • 举报
回复
Debag` 线程问题 Swing VS main 线程 public synchronized void paint(Graphics g)
希望对你有用 \(^o^)/~ 试试吧 我还没试呢 o(╯□╰)o
小绵羊 2011-10-14
  • 打赏
  • 举报
回复
Swing的JComponent以及其子类的绘制默认是使用了双缓冲的,例如JPanel
小绵羊 2011-10-14
  • 打赏
  • 举报
回复
双缓冲机制
chute 2011-10-14
  • 打赏
  • 举报
回复
我运行也是打印出2句paint() is called !
SasONsoft 2011-10-12
  • 打赏
  • 举报
回复
帮顶~
huntor 2011-10-12
  • 打赏
  • 举报
回复
说说是在什么系统、java版本下遇到的问题
Kende0120 2011-10-12
  • 打赏
  • 举报
回复
这些基本设置安装时都已经设置好的,应该没问题。
我再找找其他原因吧


[Quote=引用 14 楼 k3108001263 的回复:]
使用万能方法试试:

Java code


////////////////////////////////////////////////////////////////////////////////////////////////
下载安装对应版本的JDK:
64位操作系统:[url=http://download.oracle.com/otn-pub/java/jdk/7/……
[/Quote]
Kende0120 2011-10-12
  • 打赏
  • 举报
回复
系统 xp sp3
java 1.6.0_26

有何良策?

[Quote=引用 16 楼 huntor 的回复:]
说说是在什么系统、java版本下遇到的问题
[/Quote]
Kende0120 2011-10-11
  • 打赏
  • 举报
回复
我没有概念混乱,
我的问题很简单,以上代码 正常的运行结果是 打印 paint() is called ! 1次,
而我的电脑上运行结果是 打印 paint() is called ! 2次,也就意味着
我重载的paint方法被调用了2次,我不知道原因在哪来。

我在其他电脑上运行过了,结果正常,只打印了一次,
估计不是程序的问题,和我电脑的运行环境有关。 真麻烦!


[Quote=引用 8 楼 k3108001263 的回复:]
打印出一句 paint() is called ! , 意味着调用一次

楼主你哪里概念混乱啦
最初你说调用两次,我一开始以为你的程序会输出两句,paint() is called !
现在看来是你自己 编造的调用两次
[/Quote]
Alexander 2011-10-11
  • 打赏
  • 举报
回复
不清楚LZ那儿是什么状况,在下直接复制后运行,只会输出一句。
一蚊惊人小号 2011-10-11
  • 打赏
  • 举报
回复
看到这个东西http://javapub.iteye.com/blog/763970,不过好像没有效果,楼主试试
打油的程序员 2011-10-11
  • 打赏
  • 举报
回复
打印出一句 paint() is called ! , 意味着调用一次

楼主你哪里概念混乱啦
最初你说调用两次,我一开始以为你的程序会输出两句,paint() is called !
现在看来是你自己 编造的调用两次
打油的程序员 2011-10-11
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 kende0120 的回复:]

是打印出2次的。

paint()下也有这一句,
System.out.println("paint() is called !");
所以我才知道是被调用2次的。



引用 5 楼 k3108001263 的回复:
引用 4 楼 kende0120 的回复:

[Quote=引用 3 楼 k3108001263 的回复:]
引用 2 楼 kende0120 的回复:
……
[/Quote]

你的类作为子类继承JPanel重写了paint方法
父类调用paint方法就是调用你重写后的方法 --------------->>发生多态现象
所以会打印出一句 paint() is called ! ,而不是两句
加载更多回复(9)

62,634

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧