Java GUI中的paint方法疑难解析

来源 :科技风 | 被引量 : 0次 | 上传用户:snsjgl
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  摘要:在进行Java GUI编程时,程序利用paint(Graphics g)方法来实现组件的绘制;然而Java的绘图机制是怎样的,paint方法又是何时调用、如何调用,且每次调用时paint方法的执行次数是怎样的?轻量级和重量级组件调用paint有哪些区别等,本文作者将针对这些问题,用案例分析的方法来一一解答。
  关键词:绘图机制;paint;调用
  学过Java程序设计语言的朋友都知道,在学习Java GUI编程时,我们都知道paint方法是用来绘制图形的。有了paint方法,我们可以在Java中绘制各种漂亮的组件,或开发漂亮炫酷的游戏。但是paint是如何调用的?程序启动时,paint方法执行了一次还是多次,原理是什么?另外Swing组件和AWT组件对super.paint方法是如何相应的,组件在处理动画时,对KeyListner又是如何响应的呢?关于这些细节性的问题,许多初学者总是模棱两可。笔者经过查找资料,并写程序进行验证,得出一些结果,以供分享。
  问题1:Java的绘图机制是怎样的?
  AWT是使用回调机制来处理绘画的,并且这种机制对轻量级和重量级组件相同。也就是说我们需要把渲染组件的代码写在一个可覆盖的特殊的方法中,这个方法是public void paint(Graphics g);其中 Graphics是图形上下文对象,用来完成具体的绘制工作。paint方法由AWT框架调用或者由程序自身通过repaint方法来调用。
  问题2:画图时,paint是何时调用,如何调用,调用几次的问题。
  Java绘图时,用到的paint方法继承自AWT中的Component方法,该方法在对象加载时自动调用,用来绘制该组件内部的所有图形图像。使用repaint()方法,可以再次调用paint方法,实现组件的重绘。但是paint方法是什么时候开始执行,执行了几次呢?下面我们用例子,来加以分析。
  public class Test extends Applet//引入包的代码省略
  {Image img = null;int t =0;
  public void init(){System.out.print("初始化====");
  img = getImage(getCodeBase(),"1.jpg");}
  public void paint(Graphics g)
  {t++;System.out.print("我是paint===="+t+"");
  g.fillRect(50,50,80,80);//代码段1,绘制矩形
  // g.drawImage(img,50,50,this); //代碼段2,绘制图形}}
  执行代码段1的结果:
  初始化====我是paint====1
  执行代码段2的结果:
  初始化====我是paint====1我是paint====2……我是paint====47
  从上面结果可以发现,启动浏览器时,系统自动调用init()方法进行程序初始化,接着系统自动找到paint()方法对图像进行绘制。而且paint()方法调用的次数,跟绘制的内容有关,图形简单时,可能执行一次,图像复杂时,可能会自动调用很多次,直到图形图像完全绘制成功。另外还有当组件大小发生改变,或组件有坏点(damage)需要被修复时,系统都会自发地调用repaint方法,进行组件的重绘。
  问题3:Java程序绘图时,JPanel和Panel对super.paint()的响应问题。
  Java通过调用paint()方法来绘制组件,但是 AWT框架中轻量级组件与重量级组件实现代码还是有区别的。
  轻量级组件的绘制依赖与包含关系阶层中的重量级祖先组件,当这个祖先组件被通知绘制时,它将把绘制请求转化为绘制自身上任何可见的子孙组件,这个方法是由java.awt.Container中的 paint() 方法来完成的,因此任何Container的子类,在覆盖paint方法时一定要记得调用super.paint()来保证,它上面的轻量级子孙组件都被绘制到了。代码可以这样来完成:
  public class MyContainer extends Container {
  public void paint(Graphics g) { // 先绘制自身内容, 然后确保轻量级子组件被绘制
  super.paint(g);}}
  下面我们将通过案例,来观察:
  class myPanel extends JPanel implements KeyListener //重要代码:继承JPanel/Panel
  {int x=50;public myPanel(){addKeyListener(this);} //为面板增加键盘监听器
  public void paint(Graphics g){super.paint(g);//重要代码段:super.paint
  g.setColor(Color.orange); g.fillRect(x, 50, 60, 60);}//设置画笔颜色,填充矩形
  public void keyPressed(KeyEvent e){x=x+10;repaint();//释放键盘,矩形向右移动10像素;}
  public void keyTyped(KeyEvent e){}
  public void keyReleased(KeyEvent e){}}
  创建myPanel对象p,设置背景色为青色,同时在面板p上添加标签“测试super.paint()”,程序将出现四种情况,对应3种效果。
  (1)面板继承JPanel,且paint方法中调用super.paint(),所得结果如图2。
  (2)面板继承JPanel,且paint方法中没有调用super.paint(),所得结果如图1。
  (3)面板继承Panel,且paint方法中没有调用super.paint(),所得结果如图3。
  (4)面板继承Panel,且paint方法中调用super.paint(),所得结果如图2。
  问题4:处理动画时,JPanel和JApplet等Swing组件对KeyListner无响应的问题。
  为面板增加键盘监听器KeyListner,若面板继承java.awt.Panel,那么当程序运行时,每敲击一次键盘,上述案例中的矩形方块开始向右移动10个像素的距离;但是若面板继承javax.swing.JPanel,敲击键盘,则无任何相应动作。这又是什么原因引起的呢?
  经过实验分析,笔者发现JPanel等Swing组件在渲染完成后,无法获取focus,所以我们只需要上层容器setvisible(true)之前,先设置 p.requestFocus();为面板对象获取焦点即可。
  以上分析,希望对爱好Java GUI编程的学习者提供帮助。
其他文献
SUN1998财年第二季度营收额24.5亿美元,比去年增长了18%。中港区前两个季度都超额完成了销售额的任务,增长30%到40%,超过公司的全球增长率。搬了新家的SUN说:“唯一能与微软叫板
1998年,中国计算机市场仍在一路攀升,但与前几年相比已大打折扣。计算机发展与用户应用水平脱节的矛盾是捂也捂不住了。 电脑普及到今天,有多少人能说出网络给自己带来什么?
不久前Netscape公司公开了Communicator套件的源代码,允许外界开发人员发展该软件,同时保持Netscape公司的市场竞争力。这一举动给IT界带来了不小的震动,加上IBM宣布对免费系
"抢枢"是内蒙古自治区鄂温克人在同自然界搏击中流传下来的一项古老的民间传统体育竞技项目,它集合了鄂温克人在日常游牧、狩猎过程中的众多技能,以独特的比赛方式,锻造了鄂温
当今社会随着信息科学技术的快速发展,人们对大数据的关注程度越来越高,目前也变得越来越热门。由于大数据在各行各业都会带来一定的经济效益,所以它的发展前景很大。数据库
PDM(产品数据管理)是企业信息集成的核心技术。与以前的信息管理技术相比,现在的PDM技术更复杂、范围更广、变化速度更快,所以企业如何应用好PDM技术是非常重要的。目前,PDM
摩尔是“Shopping摩尔”的译音俗称,意指大型摩尔,即由一个管理机构统一组织、协调和规划,把一系列零售商店,服务机构有机协调地组织在一起,提供各式服务并能结合休闲、娱乐活动,以
加入WTO对于我国而言,不仅在经济和政治方面会产生深远的影响,而且还将给中国的法治环境和建设带来机遇和挑战。在这一过程中,WTO直接或间接地对政府以及政府行为提出了许多新要
在推动教学改革以及落实素质教育的过程之中,山东劳动职业技术学院提出了"卓越技师"这一重要的概念,作为一种培养高端技能人才的创造性模式,"卓越技师"以现有的专科学历为基
在竞争日益激烈的现代企业中,不间断电源(UPS)经常意味着不间断工作,持续工作常常意味着更有效地把握商机,所以,UPS也常常成为企业成功的必备一环。本期“造型指导”将就如何