Java 语言程序设计 第 6 章 Java 图形与事件处理
本章主要内容: 6.1 图形与图形的描绘 6.1 图形与图形的描绘 图形绘制特点及绘图工具 paint() 图形绘制特点及绘图工具 paint() Graphics 类 Graphics 类 Java 2D 画布 Canvas 画布 Canvas 6.2 事件处理机制 6.2 事件处理机制 事件处理机制 事件处理机制 事件类 事件类 鼠标事件 鼠标事件 事件适配器 事件适配器 键盘事件 键盘事件 焦点事件 焦点事件
6.1 图形与图形的描绘 图形绘制特点及绘图工具 paint() 1 、图形绘制特点 在一个二维的 Java 图形界面坐标系中,该坐标的原点在 组件的左上角,坐标的单位是像素。 X 轴在水平方向从左 至右, Y 轴在垂直方向从上向下,如图所示。
6.1.1 图形绘制特点及绘图工具 paint() 2 、绘图工具 paint() 方法 任何一个图形对象( java.awt.Component 的 子类)使用 paint() 方法为绘图工具就可以画出 线条、矩形、圆形等各种图形来。该方法为: public void paint(Graohics g) ; 这里,参数 java.awt.Grephics 类为绘图对象,绘图工 具 paint() 通过 Grephics 对象绘制具体的图形。 paint() 方法在程序执行后会被自行调用。而在 程序中需要执行 paint() 方法,一般是调用 repaint() 方法,以清除旧图,重新绘制新图, 该方法称为重绘。
6.1.2 Graphics 类 Graphics 类是绘图对象,它是一个抽象类, 不能直接创建 Graphics 对象。 1 、绘图方法 Graphics 类包含了大量的绘图方法,常 用的绘图方法见教材表 6.1 。
【例 6-1 】 绘制直线、矩形和圆的简单图形。 public void paint(Graphics g) { g.drawLine(50,50,120,120); g.drawRect(50,50,70,70); g.drawOval(70,70,90,90); } 使用 Graphics 对 象绘制各种图形 程序中没有显式调用 paint() 方法,它在 main() 方法中被自行调用
【例 6-2 】 绘制一个多边形图形。 核心语句 : public void paint(Graphics g) { int x[] = {80, 190, 150, 50}; int y[] = {80, 30, 170, 210}; int pts = x.length; g.drawPolygon(x, y, pts); }
6.1.2 Graphics 类 2 、设置颜色 ( 1 )颜色 颜色 RGB 红 蓝 0 0 绿 00 黄 0 紫 0 青 0 白 黑 000 灰 128
6.1.2 Graphics 类 ( 2 ) Color 类 使用 Graphics 类设置颜色,首先要创建颜色类 Color 的对象,创建颜色对象的构造方法为: public Color(int r, int g, int b); 其中,整型参数 r 、 g 、 b 的取值范围为 0 ~ 255 , 分别代表红、绿、蓝三基色。
6.1.2 Graphics 类 也可以使用 Color 类的静态常量作颜色对象的 参数,这时,创建颜色对象的构造方法为: public Color(Color. 颜色静态常量 ); 其颜色静态常量取值为 red( 红色 ) 、 blue( 蓝色 ) 、 green( 绿色 ) 、 orange( 橙色 ) 、 cyan( 青绿色 ) 、 yellow( 黄色 ) 、 pink( 粉红色 ) 、 white( 白色 ) 、 black( 黑色 ) 等。
6.1.2 Graphics 类 Graphics 类可以使用表 6.3 所示的 get/set 方法控制绘 图的色彩和使用不同字体。 getColor() 获得当前图形的色彩 setColor(Color c) 设置当前图形的色彩,参数 Color 为颜色类 getFont() 获得当前字体 setFont(Font font) 设置当前字体,参数 Font 为字体类 getClip() 获取当前的剪贴板内容。 setClip(int, int, int, int) 将指定的矩形设置为当前的剪贴区 。
【例 6-3 】 绘制用色彩填充的笑脸图 形。 核心语句 : 15 public void paint(Graphics g) 16 { 17 g.setColor(Color.yellow); 28 g.fillOval(35,30,210,210); 19 g.setColor(Color.black); 20 g.fillArc(70,70,150,150,180,180); 21 g.setColor(Color.yellow); 22 g.fillArc(70,75,150,130,180,180); 23 g.setColor(Color.black); 24 g.fillOval(80,100,30,30); 25 g.fillOval(180,100,30,30); 26 }
6.1.2 Graphics 类 3 、设置字体 其中 name 为逻辑字体名, style( 风格 ) 是 Font.PLAIN( 正常字体 ) 、 Font.BOLD( 黑体 ) 或 Font.ITALIC( 斜体 ) 的组合, size 是字号大小,字号 越大字体越大。 我们可以用 Graphics 类的 setFont(Font f) 方法 来设置字体。 Font f = new Font(String name,int style,int size);
【例 6-4 】编写程序以创建不同的风格 和大小的可利用的逻辑字体。
6.1.3 Java 2D 1 、控制线条的粗细 首先使用 Line2D 类创建直线对象 : Line2D line=new Line2D.Double(50,50,120,50); 再使用 BasicStroke 类创建一个供画笔 paint() 方法选择 线条粗细的对象。 public BasicStroke(float width, int cap, int join); width - 画笔线条粗细 cap – 线条两端的形状 join – 线条中角的处理 graphics 类还有一些不足,例如缺少改变线条粗细的方法,也 缺少填充一个对象的方法。 Graphics 2D 可以解决这些问题。
【例 6-5 】设置线条粗细 Graphics 2D 对象通过调用 setStroke(BasicStroke a) 方法来设置线条形状, 并用 draw() 方法绘制出线条。
6.1.3 Java 2D 2 、填充图形 Graphics2D 对象调用 fill() 方法用颜色填充图 形。 Graphics2D 对象还可以通过 GradientPaint 类定义一个颜色对象,实现渐变颜色填充图形。 GradientPaint 类的构造方法为: GradientPaint(float x1,float y1,Color color1,float x2,float y2, Color color2,boolean cyclic) ;
【例 6-6 】用渐变颜色填充图形。
6.1.4 画布 Canvas 画布 Canvas 类是一个用来绘制图形的矩形 组件,在画布中可以响应鼠标和键盘事件。
6.1.4 画布 Canvas 1 、创建画布对象 Canvas 的构造方法没参数,所以使用简 单的语句就可以创建一个画布对象: Canvas mycanvas = new Canvas(); 在创建了 Canvas 对象后,一定要调用 setSize() 方法确定这个画布的大小。 2 、常用方法 paint ( Graphics g ) ; update(Graphics g); repaint();
【例 6-7 】通过一个窗体的文本框输入多边形的边数, 随机产生多边形各折线的坐标位置,在画布上绘制 出一个多边形。
【例 6-8 】设计一个在窗体中可上下左右移 动的小方块的程序。 本程序的设计思想和【例 6-7 】类似,程序由二个类组 成:窗体主类(表现层)负责控制,确定所有组件 的位置,处理用户对方块的操作。画布 MoveCanvas 类(逻辑层)负责绘图,其方法 moveUp() , moveDown() , moveLeft() , moveRight() 分别响应窗体主类 actionPerformed ()方法的对应的 按钮事件,再调用 repaint 方法来刷新 图像。
6.2 事件处理 在事件处理的过程中,主要涉及三类对象, 它们分别是: ( 1 ) Event 事件:实现用户对图形界面组件 的操作,用 Java 语言描述并以类的形式出 现,例如键盘操作对应的事件类是 KeyEvent 。 ( 2 ) Event Source 事件源:事件发生的场 所,通常就是各个组件,例如按钮 Button 。 ( 3 ) Event handler 事件处理者:接收所发 生的事件并对其进行处理的对象,也称为监 听器。 事件处理机制
授权处理机制
6.2.1 事件处理机制 授权处理模式的结构 : 使用授权处理模式进行事件处理的一般方法如下: ( 1 )对于某种类型的事件 XXXEvent, 要想接收并 处理这类事件,必须定义相应的事件监听器类, 该类需要实现与该事件相对应的接口 XXXListener ; ( 2 )事件源实例化以后,必须进行授权,注册该 类事件的监听器,使用 addXXXListener(XXXListener ) 方法来注册监 听器。
6.2.2 事件类 1 、低级事件与高级事件 低级事件: KeyEvent ( 键盘事件:键按下、释 放) ; MouseEvent ( 鼠标事件:鼠标单击, 移动) 。 高级事件 : ActionEvent (动作事件:按钮按 下, TextField 中按 Enter 键等) 2 、事件监听器 每类事件都有对应的事件监听接口,如: MouseEvent --> MouseListener, KeyEvent --> KeyListener 等。
6.2.2 事件类 3 、 事件类别及监听器接口 (见教材 P175 ) 事件类别描述信息接口名事件处理方法 ActionEvent 激活组件 ActionListener actionPerformed(ActionEvent ) ItemEve nt 选择项目 ItemListener itemStateChanged(ItemEven t) MouseE vent 鼠标移动 MouseMotionL istener mouseDragged(MouseEv ent) mouseMoved(MouseEven t) 鼠标点击 等 MouseListener mousePressed(MouseEve nt) mouseReleased(MouseEv ent) mouseEntered(MouseEve nt) mouseExited(MouseEvent) mouseClicked(MouseEve nt)
6.2.3 鼠标事件 与鼠标的事件有关可以分为两类: (1) 主要针对鼠标的坐标位置进行检测,使用 MouseListener 接口; (2) 主要针对鼠标的拖曳状态进行检测,使用 MouseMotinListener 接口。
【例 6-9 】事件处理示例。 (见教材 P176 )
6.2.4 事件适配器 1 、事件适配器( EventAdapter ) java.awt.event 包中定义的事件适配器类包括以下 几个: (1) ComponentAdapter( 接收组件事件适配器 ) (2) ContainerAdapter( 接收容器事件适配器 ) (3) FocusAdapter( 接收焦点事件适配器 ) (4) KeyAdapter( 接收键盘事件适配器 ) (5) MouseAdapter( 接收鼠标事件适配器 ) (6) MouseMotionAdapter( 接收鼠标运动事件适配 器 ) (7) WindowAdapter( 接收窗口事件适配器 )
6.2.4 事件适配器 2 、用内部类实现事件处理 内部类( inner class )是被定义于另一个类 中的类,使用内部类的主要原因是由于: (1) 一个内部类的对象可访问外部类的成员方法 和变量,包括私有的成员。 (2) 实现事件监听器时,采用内部类、匿名类编 程非常容易实现其功能。 (3) 编写事件驱动程序,内部类很方便。 【例 6-10 】使用事件适配器及内部类设计记录鼠标位置的程序。
6.2.4 事件适配器 3 、用匿名类实现事件处理 当一个内部类的类声明只是在创建此类 对象时用了一次,而且要产生的新类需继承 于一个已有的父类或实现一个接口,才能考 虑用匿名类,由于匿名类本身无名,因此它 也就不存在构造方法,它需要显式地调用一 个无参数的父类的构造方法,并且重写父类 的方法。所谓的匿名就是该类连名字都没有, 只是显式地调用一个无参的父类的构造方法。 【例 6-11 】 使用匿名类设计记录鼠标位置的程序。
6.2.5 键盘事件 在 Java 中,当用户使用键盘进行操作时,就会 产生 KeyEvent 事件。监听器要完成对事件的 响应,就要实现 KeyListener 接口,或者是继 承 KeyAdapter 类,实现对类中方法的定义。
6.2.5 键盘事件 在 KeyListener 接口中有如下 3 个事件: (1)KEY_PRESSED: 键盘按键被按下所产生的事 件。 (2)KEY_RELEASED: 键盘按键被释放所产生的 事件。 (3)KEY_TYPED: 键盘按键被点击所产生的事件。 在实现接口时,对应的上面 3 个事件的处理方法 是: keyPressed(Event e); keyReleased(KeyEvent e); keyTyped(keyEvent e);
【例 6-12 】设计一个程序,在界面上安放 3 个按钮, 用户可以通过按动键盘上的方向键移动这些按钮组 件。
6.2.6 焦点事件 用户对一个组件进行操作,先要让其获得焦点。 例如文本框得到焦点时会出现闪烁光标, 而按 钮则在按钮标签周围显示矩形框等。 在组件得到或失去焦点时会产生 FocusEvent 事 件。 要处理这些事件使用焦点监听器 : FocusListener 接口 ( 或缺省适配器类是 FocusAdapter) 。 它的方法有 : void focusGained(FocusEvent e) 获得键盘 焦点 void focusLost(FocusEvent e) 失去键盘焦点
【例 6-13 】设计一程序,可以用 Tab 鍵改变文本框 的焦点。 【例 6-14 】设计一个由 3 段数值组成的序列号输入 程序,演示从组件中转移焦点。
本章结束!