<!--CTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//E--><!-- saved from url=(0070)http://www.eclipse.org/articles/Article-Progress-Monitors/article.html -->
怎么正确的使用SWT进度条
摘要
使用进度条监视器并不像看起来的那么简单,在使用时很容易犯错。这取决于各种因素,像底层实现,显示方式,是否被设定固定数目的工作条目,是否使用了SubProgressMonitor 嵌套,等等。结果可能是完全没问题,也可能是 让人挠头,或者彻底不可用。
本文将指导怎样有效的使用进度条监视器。
使用进度条监视器
在许多简单的惯例中,有一条是“只知道所知道的,并且仅限于此”。这就是说,不能假设完全了解你所不知道的事情。就像,你不能想当然的认为进度条监视器就是你在IDE中看到的那些图片样子的东西。
IProgressMonitor
通常,所有的进度条操作都是通过IProgressMonitor接口.进度条监视器具有4中状态,通过接口只可以测到一种状态(当监视器被取消时)。状态的改变是通过如下方法的作用: beginTask(), done() and setCanceled().
- PRISTINE
IProgressMonitor实例被初始化之后,方法beginTask() 被调用之前的状态。
- IN_USE
方法beginTask()被调用之后的状态,这里要注意 beginTask()只能被调用一次,
- FINISHED
done()被调用之后的状态, 它也只能调用一次,并且只能在 beginTask()之后调用。
- CANCELED
进度条被取消之后的状态。
要以以下的模式使用进度条:
monitor = ?
// 获取进度条实例,现在处于 pristine 状态
try
{
monitor.beginTask(?
// 执行工作任务
}
finally
{
monitor.done()
}
The 一定到保证 done() 最后被执行。
子任务用代理使用进度条监视器
beginTask()被调用不要多于一次,这种错误经常发生。进度条被传给子任务,子任务没有意识到进度条已经执行了beginTask(),还是按照规定的契约,执行beginTask()方法。除非子任务对此了解,否则传递进度条实例是十分错误的。一般情况下,接受到进度条实例的代码应该假设此实例自己会遵守beginTask()/done()契约。如果子任务也需要进度条,就应该使用SubProgressMonitor作为代理,封装传入的进度条实例。
如下为样例:
monitor = ?// 获取进度条实例
try
{
monitor.beginTask(?
// 执行任务
?BR> // 创建一个子任务
someThing.doWork(new SubProgressMonitor(monitor,?)
// // 创建右一个子任务
anotherThing.doWork(new SubProgressMonitor(monitor,?)
}
finally
{
monitor.done()
}
每一个doWork()调用得到一个新的SubProgressMonitor 实例。
管理条目个数
如果确实不知道确切的条目总数,不要随意猜测数字。如果猜大了,数字会走的很慢,然后突然到达100%;如果猜小了,那么会很快到达终点,并且永远停在那里。没有确切总数的话,填写 IProgressMonitor.UNKNOWN就可以了。
怎样调用 beginTask() 和worked()
通常你可以通过两种方式得出你究竟要处理多少条目:一是调用许多不同的方法来得到结果,二是在一个集合中为每一个实例调用同一个方法。每种方式你都可以知道总的条目数(方法的个数或集合的大小)。
你应该将按比例测量出你的总数。如果总数是3 (每个条目工作为worked(1)),你可以把比例定为1000,总数为3000, (每个条目工作为worked(1000) ). 当你要通过SubProgressMonitor将工作传递到子任务中,就要应用这种方式。因为子任务内部的总数和外部是不同的,也许比你定的总数大许多。你要给它们一些缓冲润滑的空间。这样可以避免进度条执行时视觉上的便扭。
样例:
monitor = ?
// 取到进度条监视器
int total = 3 // 总数为3
try
{
monitor.beginTask(total)
// 条目1
this.doPart1()
monitor.worked(1)
// 条目 2
this.doPart2()
monitor.worked(1)
// 条目 3
this.doPart3()
monitor.worked(1)
}
finally
{
monitor.done()
}
这里没有必要按比例放大,也没有集合动态计算。
更详细的样例:
monitor = ?
int total = thingyList.size() * 3 + 2
try
{
monitor.beginTask(total)
// 条目 1
this.doBeforeAllThingies()
monitor.worked(1)
// 条目 2 to 倒数第二个
for (Thingy t : thingyList)
{
t.doThisFirst()
monitor.worked(1)
t.thenDoThat()
monitor.worked(1)
t.lastlyDoThis()
monitor.worked(1)
}
// 最后一条
this.doAfterAllThingies()
monitor.worked(1)
}
finally
{
monitor.done()
}
混合使用子任务
在使用子任务的时候,子任务的总数就是分配给它的比例数。
monitor = ?
int scale = 1000
int total = 3
try
{
monitor.beginTask(total * scale)
// item 1
this.doPart1()
monitor.worked(1 * scale)
// item 2
this.doPart2(new SubProgressMonitor(monitor, 1 * scale)) //分配一个条目
monitor.worked(1 * scale) // 这里是不需要的,因为任务的管理有子任务负责
// 条目 3
this.doPart3()
monitor.worked(1 * scale)
}
finally
{
monitor.done()
}
You worked().
不要将 IProgressMonitor.UNKNOWN 传给创建的 SubProgressMonitor()
子任务进度条的实现只是盲目的使用传入的总数进行计算,当它接受到的是一个负值(IProgressMonitor.UNKNOWN为-1) 它也是按照惯例来进行计算,所以你看到的结果是进度条往回走。 IProgressMonitor.UNKNOWN不能在子任务进度条中使用,但是在父进度条中使用没有这种问题。
取消
上面的例子中,都没有判断进度条是否被取消。在实际使用中,推荐要及时的进行判断。
monitor = ?
try
{
monitor.beginTask(thingyList.size())
for (Thingy t : thingyList)
{
if(monitor.isCanceled())
throw new OperationCanceledException();
t.doSomething()
monitor.worked(1)
}
}
finally
{
monitor.done()
}
The 空进度条
这样可以使调用者不用必须传入monitor,只要输入null 就可以了。
public void doIt(IProgressMonitor monitor)
{
if(monitor == null)
monitor = new NullProgressMonitor();
try
{
monitor.beginTask(thingyList.size())
for (Thingy t : thingyList)
{
if(monitor.isCanceled())
throw new OperationCanceledException();
t.doSomething()
monitor.worked(1)
}
}
finally
{
monitor.done()
}
}
结论
只要遵循这些规则,在使用进度条的时候就不会碰到麻烦。如果不信邪,想当然的用,迟早会出现奇怪的视觉显示,你的客户又要不停的抱怨了。
分享到:
相关推荐
SWT本身并不直接提供媒体播放功能,但可以通过与其他库如VLCJ(使用VideoLAN的VLC播放器引擎)或JavaFX的Media API结合,来实现播放功能。 3. **全屏模式**:在SWT中,可以使用Shell的`setFullScreen(true)`方法来...
正确地使用布局管理器,可以使界面看起来整洁且适应不同屏幕尺寸。 8. **选项卡(TabFolder)**:`TabFolder`组件可以将多个页面(TabItem)组织成一个选项卡式界面,用户可以通过点击不同的标签切换内容,非常适合...
在使用SWT时,需要确保你的项目正确地导入了这个库,并且对于不同操作系统,可能需要对应版本的SWT库,因为每个操作系统可能有自己的特定实现。 SWT的主要特点包括: 1. **性能**:SWT直接调用操作系统提供的API,...
3. **丰富的控件集**:SWT提供了一套丰富的控件,如树形视图、表视图、进度条、复选框、单选按钮等,这些控件的外观和行为与操作系统保持一致。 4. **事件驱动**:SWT采用事件驱动模型,通过监听用户的交互动作,如...
3. **丰富的组件集**:SWT包含各种标准的GUI组件,如按钮、文本框、列表、树形视图等,以及高级组件如表单、进度条、颜色选择器等。 4. **事件驱动模型**:SWT采用事件驱动编程模型,允许开发者响应用户的交互,如...
为了在Eclipse IDE之外运行SWT程序,你需要确保已经安装了正确的JRE,并且将SWT库文件添加到类路径中。 #### 13. 小结 SWT为Java开发者提供了一种强大的工具集,用于创建高性能的图形用户界面。通过掌握SWT的基础...
学习SWT不仅需要掌握控件使用和布局管理,还需要了解事件处理、线程管理和数据绑定等概念。同时,熟悉Eclipse插件开发也是提升SWT技能的重要途径,因为很多SWT应用都作为Eclipse插件存在。 通过提供的"src"文件,...
4. **错误和警告消息**:正确地向用户显示错误或警告信息,包括ErrorDialog和MessageBox的使用。 此外,25章可能还会涉及对话框的生命周期管理、对话框返回值的处理以及如何在不同工作台窗口中打开对话框。 总之,...
开发者可以通过API接口自定义浏览器的行为和外观,比如设置页面加载进度条,调整浏览器窗口大小,或者处理JavaScript与Java之间的通信。 在实际使用中,你需要将DJ NativeSwing库添加到你的Java项目构建路径中。...
在Java 飞鸽文件传输系统中,SWT可能被用来创建用户友好的界面,包括文件选择对话框、进度条、状态提示等,以便用户能够直观地监控文件传输的过程。 基于TCP协议的文件传输确保了数据的可靠性和顺序性。TCP...
- **使用工厂模式或单例模式来管理Socket连接,确保连接的复用和正确关闭**。 综上所述,Java客户端自动更新涉及到网络通信、文件处理、版本控制等多个方面,通过Socket通信实现,可以实现高效且可靠的更新机制。...
2. **网页渲染**:WebBrowser控件不仅能够加载网页,还能执行JavaScript,这意味着动态内容也能被正确地呈现。这对于包含交互元素或动态更新的网页来说至关重要。 3. **屏幕截图**:在Winform应用中,获取...
Window Builder是Java开发工具中用于图形化界面设计的重要组件,它能够帮助开发者以可视化的方式快速构建Swing或SWT应用程序的用户界面。使用Window Builder,开发者可以直观地拖放组件,设置属性,以及管理布局,...
EJB中JNDI的使用源码例子 1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件...
这种策略被称为异步编程,是Java GUI编程中的关键概念,特别是在Swing和 SWT(标准窗口工具包)等库中。理解如何正确处理主线程与后台线程的交互对于编写流畅、响应式的用户界面至关重要。通过合理地分配任务到不同...