一概述
首先我们来看看构造这个媒体播放器要达到什么样的目标确定了目标也就确定了代码量和程序的复杂程度本文的媒体播放器要达到如下目标
媒体播放器是一个菜单驱动的简单AWT应用
媒体播放器包含一个文件菜单文件菜单包含三个菜单项
打开用来打开媒体文件
循环是播放一次(默认)还是重复播放
退出退出程序
媒体播放器可以在多种平台上运行
媒体播放器的核心功能通过JMF(Java Media Framework)API实现JMF扩展了JSE平台的多媒体能力允许Java应用和Applet截取回放转换包括音频和视频在内的多种媒体JMF支持多种媒体格式具体请参见Supported Media Formats and Capture Devices
二初步设计
我们把这个媒体播放器的设计分成两个部分GUI设计伪代码设计在GUI设计中我们要了解构成程序的各个GUI部件在伪代码设计中我们用自然语言写出程序运行原理
GUI设计
媒体播放器的用户界面包含一个主窗口一个菜单和一个打开文件的对话框首先我们来看看主窗口的设计主窗口应该把窗口标题显示为媒体播放器显示文件菜单显示彩色背景的欢迎信息图一显示了程序刚启动时的主窗口
图一媒体播放器的主窗口
文件菜单包含三个菜单项打开菜单显示一个对话框用来选择媒体文件的位置循环菜单决定媒体文件只播放一次(默认)还是反复播放(当菜单被选中)最后退出菜单关闭程序另外点击主窗口右上角的关闭按钮也可以关闭程序请参见图二
图二文件菜单
点击文件/打开菜单时打开媒体文件对话框出现选中媒体文件之后点击打开按钮即可打开媒体文件点击取消按钮中止文件打开操作如图三所示
图三打开媒体文件对话框
除了上面提到的部件之外媒体播放器还包含一个视觉部件一个控制面板部件视觉部件顺序播放媒体文件包含的各帧图像控制面板部件允许用户暂停开始媒体文件的回放或进行其他控制操作例如查看媒体文件信息
伪代码设计
前面我们了解了构成媒体播放器GUI的各个部件下面要开始设想一下这个程序的具体构造在正式编写代码之前我们先用伪代码的形式写出这个程序的运行过程以后正式编写代码时只需把伪代码翻译成Java代码即可下面给出了媒体播放器的伪代码描述
应用的类名称MediaPlayer
超类Frame
监听器分类动作事件控制器事件菜单项事件绘图事件窗口事件
main:
* 为MediaPlayer对象分配内存调用MediaPlayer构造函数
创建主窗口(同时隐含地创建/启动了AWT后台线程)
* 结束主程序线程此时AWT线程继续运行
MediaPlayer构造函数
* 设置主窗口的标题
* 注册窗口监听器以处理窗口关闭事件
* 创建文件菜单
* 创建打开菜单项
* 把MediaPlayer对象注册成为打开菜单项动作事件的监听器
* 把打开菜单项加入文件菜单
* 在文件菜单中加入一条水平分隔线
* 创建带检查框的循环菜单项
* 把MediaPlayer对象注册成为循环菜单项事件的监听器
* 把循环菜单项加入文件菜单
* 在文件菜单中加入一条水平分隔线
* 按照创建打开菜单项的过程创建退出菜单项
* 创建一个菜单条(MenuBar)
* 把文件菜单加入到菜单条
* 把新创建的菜单条设置为主窗口的菜单条
* 把主窗口的大小设置为*像素
* 显示主窗口
* 结束构造函数
动作监听器
当出现动作时
* 如果动作事件起源于退出菜单项
* 触发一个给窗口监听器的窗口关闭事件
* 返回
* 创建一个打开媒体文件对话框
* 把对话框的当前目录设置为上次关闭时的目录
* 显示对话框这个对话框是一个模式对话框
* 如果用户没有通过对话框选择媒体文件
* 返回
* 保存用户在对话框中选择的目录
* 如果以前已经创建JMF播放器对象
* 关闭该对象
* 根据指定的目录和名字创建一个使用file:协议的媒体定位器(MediaLocator)
对象再利用该对象创建一个JMF播放器对象
* 如果出现异常
* 显示错误信息然后返回
* 把主窗口的标题设置为媒体文件的名字
* 把MediaPlayer对象注册为来自JMF播放器对象的控制器事件
的监听器
* 让JMF播放器对象预先提取媒体内容
* 返回
控制器监听器
当控制器被关闭
* 如果JMF播放器的视觉部件存在从MediaPlayer容器拆除
视觉部件
* 如果JMF播放器的控制面板部件存在从MediaPlayer容器拆除
控制面板部件
* 返回
当媒体回放结束
* 如果循环菜单被选中
* 复位JMF播放器对象的开始时间
* 让JMF播放器对象开始播放媒体
* 返回
当预提取媒体内容结束
* JMF播放器对象开始播放媒体
* 返回
当实例化(realize)完成
* 获取JMF播放器对象的视觉部件
* 如果视觉部件存在则把它加入到MediaPlayer容器的
中间
* 获取JMF播放器对象的控制面板部件
* 如果控制面板部件存在则把它加入到MedaPlayer容器的南方
* 执行pack()操作
* 返回
菜单项监听器
当菜单项状态改变
* 切换循环菜单被选中的状态
* 返回
绘画事件监听器
paint()方法
* 如果尚未装入媒体文件
* 获得主窗口的宽度和高度
* 用蓝色填充窗口内的区域
* 创建一种字体(DialogInput/粗体)并将它设置为主
窗口的字体
* 计算欢迎信息的以像素计的宽度
* 把绘图颜色改成白色
* 在主窗口的中央显示出欢迎信息
* 调用Frame超类的paint()方法确保控制面板部件正确地画出
* 返回
update()方法
* 调用paint()方法
* 返回
窗口监听器
windowClosing
* 调用dispose以执行windowClosed
* 返回
windowClosed
* 如果已经创建JMF播放器对象
* 关闭JMF播放器对象
* 结束程序
伪代码的前面三行声明了媒体播放器的类名称超类的名称和MediaPlayer类实现的监听器带有main:前缀的行表示MediaPlayer的main()方法类似地带有构造函数前缀的行属于MediaPlayer的构造函数伪代码的其余内容分成五个监听器分区动作监听器控制器监听器菜单项监听器绘图监听器窗口监听器每一个分区分别包含一个或多个方法
三编写代码
下面我们把前面的伪代码转换成Java代码
import dia*;
import javaawt*;
import javaawtevent*;
class MediaPlayer extends Frame implements ActionListener
ControllerListener ItemListener
{
Player player;
Component vc cc;
boolean first = true loop = false;
String currentDirectory;
MediaPlayer (String title)
{
super (title);
addWindowListener
(new WindowAdapter ()
{