§ 2.4多线程的应用
? 任务
? ①使用多线程技术在后台保存文件
? ②使用进度栏实时显示文件的保存进度
2.4.1 线程与 Swing
? Swing并不是个安全的线程 。 如果试图通过多个
线程直接对用户界面的各个元素进行操作, 会
使程序出现异常 。
? 示例 2.4.1创建一个 GUI程序, 在一个线程中对
窗口中的 Swing组件进行操作, 引发异常 。
出错分析
主 线 程
事 件 调 度 线 程
工 作 线 程




创 建 窗 口 及 S w i n g 组 件
m a i n 线 程 退 出
显 示 窗 口
用 户 点 击, B a d, 按 钮
0
Swing编程的单线程原则
? 如果某个操作较为费时,则需要创建一个新线程
来执行这项操作。
? 如果某个操作需要进行长时间的输入或输出操作,
也应创建一个新线程来完成该操作
? 如果对界面的某项操作必须等待一段时间,请不
要在事件线程中调用 sleep方法,而应该使用定时
器对象。
? 在新线程中不要直接对 Swing组件进行操作,而
应通过事件调度线程来对 Swing组件进行操作。
2.4.2 定时器( Timer)
? 定时器用于按照规定的时间间隔产生一个通知
事件,执行某些操作。
? 在 Java中经常使用的定时器类( Timer)有 2个,
一个是位于 java.util包中,称为 Util定时器。
? 另一个位于 javax.swing包中,称为 Swing定时
器。
示例 2.4.3 使用 Swing定时器创建一个图形化世界
各地时差表 。
2.4.3 进度栏
? 在 JAVA中用 javax.swing包中的 JProgressBar来
实现进度栏控件 。
? 进度栏控件并不是一个线程安全的控件, 因此
如果要在多线程程序中对进度栏控件进行操作,
不能直接调用进度栏控件的 setValue方法, 而
应该通过事件调度程序来调用 Swing方法 。
? 示例 2.4.4 进度栏控件使用示例
2.4.3 进度监视器 (ProgressMonitor)
? 示例 2.4.5 在示例 2.4.4的基础上演示进度监视
对话框的使用
pmProgress = new
ProgressMonitor(ProgressMonitorExample.this,"计算中,..","
已处理 ",0,MAX);
public void actionPerformed(ActionEvent evt){
int current = wt.getCurrent();//获取工作线程当前的
进度
taData.append("当前进度,"+current+"\n");//显示当
前进度值
pmProgress.setProgress(current);//设定进度栏的当前
进度
pmProgress.setNote("已处理,
"+current+"/"+MAX);//显示提示信息
//如果工作线程已完成任务
if (wt.isFinished()||pmProgress.isCanceled()){
wt.stop();//停止工作线程的运行
timer.stop();//停止定时器
btnStart.setEnabled(true);//恢复按钮可用
}
}
任务解决
( a )
( b )
小结
? 线程与 Swing
? 定时器( Timer )
? 进度栏 (ProgressBar)
? 进度监视器 (ProgressMonitor)