Graphics: 1. java.awt.Graphics;2.android.graphics
Canvas:1.java.awt.Canvas;2.android.graphics.Canvas
android.graphics与android.graphics.Cancas都是在android中使用的绘图工具,下一篇再记载。
在绘图时发现,大部分绘图都是继承JPanel,然后重写它的paint()方法,在其中获取Graphics来完成绘图即:
public void paint(Graphics g){
.................//do something you want to do
}
这样做的好处是可以在窗体发生改变时保存自己的绘图,应为当窗体大小改变,或是最小化,最大化时,系统都会调用窗体的repaint()方法,如果是轻量级组件就会调用该组件的paint(),否则调用该组件的update(),再由update()调用paint(),归根结底都是调用的paint()方法。注意:重写JFrame的paint()方法会导致闪烁,因为JFrame与JPanel的paint()方法来源不一样。
但我想自己获取Graphics实例来绘图,这时发现自己是不能创建Graphics实例的,Graphics都是有系统创建,然后引用的。所以在上面的重写paint方法时,系统会在调用paint方法时将已经创建的Graphics引用传入。如果想要获取Graphics,必须是在程序在jvm中运行后,即JFrame或JDialog等最高级容器已经被绘画在屏幕中时,这是graphics实例已经被创建用于画出要显示的内容,具体代码就是在setVisible(true)后就可通过getDraphics()获取Graphics实例了。因为,setVisible()实际上是调用的show()方法显示图形:
这时会通过show()方法调用repaint()方法来显示图形,这时就可以获取到graphics实例来进行绘画了,而对于JPanel等继承与JComponent的容器或组件来说,使用setVisible(true)之后是获取不了graphics的,必须将其添加到顶级容器(如JFrame)中才可以在父容器setVisible(true)后获取graphics,否则会返回null。add(Component c)是 java.awt.Container类的方法,在其中会调用addImpl(),在其中设置Component的GraphicsConfiguration,其实就是将父容器的Graphics引用传递给子组件,就是通过add()添加的组件。
而Canvas是一个绘图的轻量型组件,相较于JPanel继承了JComponent,而JComponent又继承了AWT中的Container,Container又继承了Component,Canvas只继承了Component。那么创建一个Canvas实例,该类的对象所占内存空间无疑更小,因为它所要加载的父类比JPanel小。所以如果是只要简单点的画图,还是用Canvas好。
但直接使用时发现,当窗体变化时,会导致图形失效,因为会调用paint()方法,而我们并没有使用paint()方法来绘图。获取Graphics后直接画图还是显示不出来,要让主线程睡眠一会(11毫秒),再画图就可以显示出来。
把注释取消即可正常运行,显示图形。
所以想要通过PaintEvent来实现对图形的绘制。但在JPanel中并不能添加PaintEventListener,而且既然要使用绘画事件监听,还不如直接重写paint()方法。