java第八节 GUI/图形用户界面
/*
*第8讲 GUI/图形用户界面
* AWT的基础知识
* GUI全称是Graphical User Interface,即图形用户界面
* JDK中提供了AWT和Swing两个包,用于GUI程序的设计和开发
*
* GUI组件可以分为两大类:基本组件和容器,
* 分别是java.awt.Component和java.awt.Container的直接或间接子类
*
* 程序的GUI部分由AWT线程管理
*
* 编程举例:让框架窗口显示5秒后关闭,查AWT线程的状态
*
*
*
*
* AWT事件处理
* 事件处理机制
* 三个重要的概念:
* 事件:用户对组件的一个操作,称之为一个事件
* 事件源:发生事件的组件就是事件源
* 事件处理器:某个Java类中的负责处理事件的成员方法
* 事件源,事件,事件处理器之间的工作关系
* 1 事件处理器 ->(事件监听器注册) 组件(事件源) -> 外部作用
* 2 组件(事件源) ->(生成事件对象) 事件对象
* 3 事件对象 ->(把事件对象传入事件处理器) 事件处理器
*
*
* 事件分类
* 按产生事件的物理操作和GUI组件的表现效果进行分类
* MouseEvent
* WindowEvent
* ActionEvent
* 事件的性质分类:
* 低级事件
* 语义事件(又叫高级事件)
* 事件监听器
* 一个事件监听对象负责处理一类事件
* 一类事件的每一种发生情况,分别由事件监听器对象中的一个方法来具体处理
* 在事件源和事件监听对象中进行约定的接口类,被称为事件监听器接口
* 事件监听器接口类的名称与事件类的名称是相对应的,例如:
* MouseEvent事件类的监听器接口名为MouseListener
* 编程实例:实现关闭窗口的事件处理,讲解用不同层次的事件类型来表示同一个事件源对象
*
* 处理发生在某个GUI组件上的XxxEvent事件的某种情况,其事件处理的通用编写流程
* 编写一个实现了XxxListener接口的事件监听器类
* XxxListener类中的用于处理该事件情况的方法中,编写处理代码
* 调用组件的addXxxListener方法,将类XxxListener创建的创建的实例对象注册到GUI组件上
*
*
*
* 事件适配器
* JDK中也提供了大多数事件监听器接口的最简单的实现类,称之为事件适配器(Adapter)类
* 用事件适配器来处理事件,可以简化事件监听器编写
* 编程实例:使用事件适配器类来关闭窗口
* 初学者使用事件适配器时的常见问题,解决问题的思路:
* -是方法没有被调用,还是方法中的程序代码的执行问题?
* -是方法名写错了,还是没有注册事件监听器?
* 事件适配器类的不足之处
*
*
*
* 灵活设计事件监听器类
* 如果要在事件监听器为中访问非事件源的其它GUI组件,程序该如何编写?
*
* 用匿名内置类实现事件监听器
*
* 事件处理的多重运用
* 如何知道一个GUI组件倒低能够触发哪几种事件?
* 一个组件上的一个动作可以产生多种不同类型的事件
* 一个事件监听器对象可以注册到多个事件源上
* 在一个事件源上也可以注册对同一类事件进行处理的多个事件监听器对象
*
*
* 修改组件的默认事件处理方式
* 只有在一个组件上注册了某种事件的事件监听器对象后,组件才会产生相应的事件对象
* 默认的processEvent方法调用相应的processXxxEvent方法
* 调用enableEvents((long eventsToEnable))方法,可以在即使没有注册事件监听器的情况下,组件也能够对某些类型的事件进行响应和产生相应的事件对象
* 代表组合事件类型的数值:
* 1 0 0 1......
* 包含事件类型A
* 不包含事件类型B
* 不包含事件类型C
* 包含事件类型D
* 代表事件类型A的数值 10000...
* 代表事件类型D的数值 00010...
* 编程实例:在一个窗口上显示一个按钮,一时鼠标移动到这个按钮上时,按钮就移动到了其他位置,这样,鼠标就永远无法点周到这个按钮
*
* GUI组件上的图形操作
* Graphics类与图形绘制
* Component.getGraphics方法与Graphics类
* Graphics.drawLine(int x1, int y1, int x2, int y2)方法
* Graphics.drawString(String str, int x, int y)方法
* Graphics.drawString方法的坐标参数,注意是开始是左下方法
*
* 编程举例:
* 以鼠标在窗口中按下时的位置作为起始点,鼠标释放时的位置作为终止点,在鼠标释放时将直接画出,并在每条直线的起始和终止点位置上打印出它们的坐标值
*
* 组件重绘的处理
* 组件重绘的原理
* paint(Graphics g)的作用
* AWT线程对组件重绘的调用过程
* repaint() -> AWT Thread update(清除组件表面内容调用paint()方法) paint();
* 编程实例:在窗口上画直线和打印文本的功能,并在窗口重绘后重绘窗口上的所有直线
*
* 图像显示
* 使用Graphics.drawImage(Image img, int x, int y,ImageObaserver observer)方法显示图像
* 使用Component.getToolkit.getImage(String path)语句获取Image实例对象
* 编程实例:在窗口上显示图像文件中的图像,并解决由于drawImage内部实现机制造成的图像不能显示问题,和实现图像的永久化显示
*
*
* 双缓冲技术
* Component.createImage方法创建内存Image对象.
* 在Image对象上进行绘制的结果就成了一幅图像
* 在Image对象上执地与组件表面同样的绘制,Image对象中的图像是组件表面内容的复制,当组件重画时,只需要将内存中的Image对象在组件上画出
*
* 编程实例:使用双缓冲区技术重绘组件表面的所有图形
*
*
* 常用的AWT组件
* Canvas
* Canvas是最基本和最简单的GUI功能的组件
* Canvas代表屏幕上的一块空白的矩形区域,程序能够在这个部件表面绘图,也能够捕获用户的操作,产生相应的事件
* 当要设计自定制的GUI功能的组件类时,继承Canvas将会大简化编程难度
*
* 编程实例:设计一个自定制的计时器组件,当鼠标在设时器组件上按下时,计时器开始计时,并显示计时时间,当鼠标释放时,计时器停止计时
*
* 菜单
* 一个完整的菜单系统由菜单条,菜单和菜单项组成,它们之间的关系如图:
* Java中与菜单相关的类主要有: MenuBar(菜单条)、Menu(菜单)、Menultem(菜单项)
* 编程实例:实现图中的菜单和相关事件处理
*
* Container 容器类
* Container类是所有容器类的父类,Container.add方法用于将组件添加到容器中
* Container也是Component的子类,因此也可以作为组件增加到其它容器上
*
* Component -> Container
* -----> Window
* ------> Frame
* ------> Dialog
* (BorderLayout)
* -----> Panel
* -------> Applet
* (FlowLayout)
*
* Dialog与FileDialog类
* Dialog类用于产生对话框
* 模态对话框和非模态对话框
* Dialog类的两个常用构造方法:
* public Dialog(Frame owner, String title);
* public Dialog(Frame owner, String title, boolean modeal)
* 编程实例:主框架窗口通过两个按钮分别打开一个模态对话框和一个非模态对话框,并与这两个对话框进行数据交换
*
*
* Checkbox
* Checkbox类用来建立单选按钮和多选按钮(也叫复选框)
*
* 创建多选按钮,只需要使用构造函数
* Checkbox(String lable, boolean state)
*
* 创建单选按钮,需要使用构造函数
* Checkbox(String lable, boolean state, CheckboxGroup group)
*
* 单选按钮和多选按钮的语义事件为ItemEvent,对应的监听器接口为ItemListener, 该接口只有一个itemStateChanged方法
* 编程实例:创建一个多选按钮和两个属于同一组的单选按钮,并对每个按钮的选中情况进行处理
*
*
* Choice
* Choice类用来制作单选下拉列表框
* Choice的类的语义事件为ItemEvent, 对应的监听器接口为ItemListener, 该接口中只有一个itemStateChanged方法
* 编程举例:实现图中的列表框和相关事件处理
*
* Panel与ScrollPane类
* Panel类是一个容器类,用于产生一种特殊的空白面板,可以容纳其他组件,但不能独立存在
* ScrollPane类是一种容器类,用于产生滚动窗口,通过滚动条在一个较小的容器窗口中显示较大的子部件
*
* 编程举例:如何使用ScrollPane
*
*
*
*
* 布局管理器
* 一个容器中的各个组件之间位置和大小关系就称之为布局
* Java语言提供了布局管理器来管理组件在容器中的布局,而不是直接使用位置坐标来设置各件组件的位置和大小
*
* AWT中的布局管理器类:
* BorderLayout
* NORTH(北)
* WEST(西)
* SOUTH(南)
* EAST(东)
* CENTER(中)
* 编程实例:
* 了解BorderLayout布局管理器的作用
*
*
* FlowLayout
* 编程实例:了解FlowLayout布局管理器的作用
*
* GridLayout
* GridLayout布局管理器将容器划分成若干行列的网格,在容器上添加组件时,它们会按从左到右,从上到下的顺序在网络中排列
* 在GridLayout的构造方法中,需要指定在容器上划分的网络的行,列数
*
* CardLayout
*
* 取消布局管理器
* 调用Container.setLayout(null)方法取消布局管理器设置,在这种情况下,可以调用COmponent.setBounds方法来用绝对坐标设置容器上的每个组件的大小和位置
*
* 不使用布局管理器将会给程序带来一个潜在的问题,当容器大小改变时,所有组件仍保持原来的位置和大小,将导致整个程序界面比较”难看“
*
* 编程实例:演示不使用布局管理的效果
*
*
*
* Swing和JFC
* 所有的Swing组件,位于javax.swing包中,它们是构筑在AWT上层的GUI组件,Swing组件是JComponent类的子类
* 为保证可移植性,Swing完全用Java语言编写
* Swing提供了比AWT更多的组件库,例如,JTable, JTree, JComboBox
* Swing也增强了AWT中原有组件的功能,例如:与AWT中的Button对应的Swing组件是JButton
* JFC(java Foundation Class)是指Sun对早期的JDK进行扩展的部分,集合了Swing组件和其他能简化开发的API类,包括Swing, java 2D, accessibility, internationalization
*
* 编程实例:从AWT过渡到Swing
*
*
* JFrame
* JFrame是与AWT中的Frame相对应的SWing组件
* JFrame上面只能有一个唯一的组件,这个组件为JRootPane,调用JFrame.getContentPane()方法可获得JFrame中内置的JRootPane对象
* 应用程序不能直接在JFrame实例对象中添加组件和设置布局管理器,而应该在JRootPane对象上添加组件和设置布局管理器
* 调用JFrame的setDefaultCloseOperation方法,可以设置单击窗口上的关闭按钮时的事件处理方式,
* 例如:当设置值为JFram.EXIT_ON_CLOSE时,单击JFram窗口上的关闭按钮,将直接关闭JFrame框架窗口并结束程序运行
*
* 编程实例:使用JFrame来创建程序的主框架窗口
*
* JScrollPane
* JScrollPane是与AWT中的ScrollPane相对应的Swing组件
* 最基本的JScrollPane由水平和垂直方方向的JScrollBar以及一个JViewport组件
* 调用JScrollPane.getViewport方法,可以获取代表滚动窗口中的视图区域的JViewport对象
* 调用JViewprot.setView方法,可以将滚动窗口中要显示的内容作为子组件增加到JViewprot上
* 编程实例:使用JScrollPane创建滚动窗口
*
* Swing中的标准对话框
* JOptionPane类提供了若干个showXxxDialog静态方法,可用来产生简单的标准对话框
* showConfirmDialog(Component parentComponent, Object message, String title, int optionType, int messageType)中的每个参数的意义
*
* 编程举例:使用JOptionPane类,在程序开始运行时,弹出一个对话框提示用户,在主框架窗口的关闭按钮被单击时,弹出一个对话框询问用户是否真的要结束程序运行
*
* JFileChooser类专门用来实现文件存取对话框
*
*
* 计算器界面的程序实现
* 要求:
* 单击任何按钮,按钮上面的数字或符号从左到右的顺序显示在文本框中
* 文本框中的文字是左对齐显示
*
* BoxLayout布局管理器:
* BoxLayout是在Swing中新增加的一种布局管理器,它允许多个组件全部垂直摆放或合部水平摆放
* 使用BoxLayout实现计算器界面
*
*
* 学习和开发GUI程序的建议
* 重要掌握GUI程序的一些基本原理和开发过程,通过学习AWT组件可以更容易掌握GUI程序的基本原理和开发过程,但在GUI程序开发中,应尽量使用Swing组件
*
* 查阅JDK文档中的Swing包,通读一下其中所包含的组件,以了解SWing提供了哪些GUI组件,但不必去仔细阅读每个组件的使用的帮助
*
* 只在要用到某个GUI组件时,才有必要仔细阅读这个组件的具体使用帮助,如果要快速掌握某个新遇到的组件和用法,最好是能够找到并参阅该组件的例子程序
*
* 在JDK的demo程序目录中,或是<<Java指南>>(可从SUN公司的网站上下载,英文名为The Java Tutorial)中,都能找到某些组件的应用范例
*
* 参考别人成功的应用,是快速学习和完成工作的有效方式
*
*
*思考与实践(1)
* 1 什么是事件, 事件源和事件处理器,并描述三者的工作关系
*
* 2 描述事件处理的编码实现过程
*
* 3 描述事件监听器类和事件适配器类的关系和区别
*
* 4 描述在窗口上画直线和程序编写过程和组件重绘的原理
*
* 5 为讲程中所讲的自定义计时器组件编写如下功能:允许程序设置计时器的显示文本的颜色,时间显示文本的字体大小随组件大小的改变而改变
*
* 6 结合JDK文档帮助,编写一个使用FIleDialog选择文件名的例子程序,单击主窗口上的打开按钮,打开一个文件对话框
* 并将选择的文件路径显示在主窗口上的"打开"按钮左边的文本框中,在文件对话框中可以对文件类型进行过滤
* 每次打开文件对话框时,对话框中的初始显示目录为上次选择的文件所在目录
*
* 7 修改前面实现计算器界面的程序代码,将增加单个按钮的代码用一个函数来实现,然后在一个循环语句中调用这个函数来增加所有的按钮
*
*
**/
public class Lesson8 {
/**
* Method main
*
*
* @param args
*
*/
public static void main(String[] args) {
// TODO: Add your code here
}
}