有时,在程序中运行的任务可能需要一段时间才能完成。用户友好的程序向用户提供一些指示,表明任务正在发生、任务可能需要多长时间以及已经完成了多少工作。一种表示工作的方式,也许是进度量,是使用动画图像。
另一种指示工作的方法是使用 Cursor类和Component-defined setCursor方法设置等待光标。例如,以下代码使等待光标在光标结束时显示container(包括它包含的任何未指定光标的组件):
container.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
要传达任务的完成程度,您可以使用如下进度条:
有时您无法立即确定长时间运行的任务的长度,或者该任务可能会长时间停留在相同的完成状态。您可以通过将进度条置于不确定模式来显示没有可测量进度的工作。不确定模式下的进度条会显示动画以指示工作正在进行。一旦进度条可以显示更有意义的信息,您应该将其切换回其默认的确定模式。在 Java 外观中,不确定的进度条如下所示:
Swing 提供了三个类来帮助您使用进度条:
JProgressBar
一个可视组件,以图形方式显示总任务已完成多少。使用不确定模式部分告诉您如何在任务范围已知之前为进度条设置动画以显示活动。
ProgressMonitor
不是可见组件。相反,此类的一个实例监视任务的进度并在必要时弹出一个对话框。
ProgressMonitorInputStream
带有附加进度监视器的输入流,它监视从流中读取的内容。您可以像使用Basic I/O中描述的任何其他输入流一样使用此流的实例 。您可以通过调用来获取流的进度监视器,getProgressMonitor并按照如何使用进度监视器中的说明对其进行配置。
在您看到正在运行的进度条和进度监视器后,决定是使用进度条还是进度监视器可以帮助您确定哪个适合您的应用程序。
这是一个小型演示应用程序的图片,它使用进度条来测量在自己的线程中运行的任务的进度:
//声明成员变量的地方:
JProgressBar 进度条;
...
//GUI的构建位置:
progressBar = new JProgressBar(0, task.getLengthOfTask());
进度条.setValue(0);
progressBar.setStringPainted(true);
创建进度条的构造函数设置进度条的最小值和最大值。您还可以使用setMinimum和设置这些值setMaximum。这个程序中使用的最小值和最大值是 0 和任务的长度,这是许多程序和任务的典型特征。但是,进度条的最小值和最大值可以是任何值,甚至是负值。该代码段还将进度条的当前值设置为 0。
调用setStringPainted使进度条在其范围内显示已完成任务百分比的文本指示。默认情况下,进度条显示其getPercentComplete方法返回的值,格式为百分比,例如33%。或者,您可以通过调用将默认值替换为不同的字符串setString。例如,
if ( /*...完成一半...*/ )
progressBar.setString("到了一半!");
当用户单击StartTask时,会创建并执行内部类的一个实例。
公共无效actionPerformed(ActionEvent evt){
startButton.setEnabled(false);
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
完成=假;
任务=新任务();
task.addPropertyChangeListener(this);
任务.执行();
}
Task的子类是 javax.swing.SwingWorker。该Task实例为 做三件重要的事情ProgressBarDemo:
该实例doInBackground在单独的线程中调用 。这是实际执行长时间运行的任务的地方。使用后台线程而不是事件调度线程可以防止用户界面在任务运行时冻结。
当后台任务完成时,实例调用done事件调度线程中的方法。
该实例维护一个绑定属性 ,progress该属性已更新以指示任务的进度。propertyChange每次progress更改时都会调用该方法。
有关 . _ _ _ SwingWorker_
后台任务ProgressBarDemo通过以随机间隔报告随机进度量来模拟真实任务。该方法通过更新进度条propertyChange来响应任务属性的变化:progress
公共无效propertyChange(PropertyChangeEvent evt){
如果(!完成){
int 进度 = task.getProgress();
进度条.setValue(进度);
taskOutput.append(String.format(
"已完成 %d%% 的任务。
", 进度));
}
后台任务完成后,任务的done方法重置进度条:
公共无效完成(){
//告诉进度监听器停止更新进度条。
完成=真;
Toolkit.getDefaultToolkit().beep();
startButton.setEnabled(true);
设置游标(空);//关闭等待光标
progressBar.setValue(progressBar.getMinimum());
taskOutput.append("完成!
");
}
请注意,该done方法将done字段设置为true,以防止propertyChange对进度条进行进一步更新。这是必要的,因为progress属性的最终更新可能发生在done调用之后。
设置为ProgressBarDemo2不确定模式,直到实际进度开始:
公共无效propertyChange(PropertyChangeEvent evt){
如果(!完成){
int 进度 = task.getProgress();
如果(进度== 0){
progressBar.setIndeterminate(true);
taskOutput.append("还没有进展
");
} 别的 {
progressBar.setIndeterminate(false);
进度条.setString(null);
进度条.setValue(进度);
taskOutput.append(String.format(
"已完成 %d%% 的任务。
", 进度));
}
}
}
代码中的其他更改与字符串显示有关。显示字符串的进度条可能比不显示字符串的进度条要高,并且,作为演示设计者,我们已经武断地决定该进度条应该仅在默认的确定模式下显示字符串。但是,我们希望避免在更改模式时进度条更改高度可能导致的布局丑陋。因此,代码保留在调用中,setStringPainted(true)但添加了调用,setString("")因此不会显示任何文本。稍后,当进度条从不确定模式切换到确定模式时,调用setString(null)会使进度条显示其默认字符串。
我们没有做的一项更改是progressBar.setValue从progress事件处理程序中删除调用。该调用不会造成任何伤害,因为不确定的进度条不使用其 value 属性,除非可能将其显示在状态字符串中。事实上,让进度条的数据尽可能保持最新是一种很好的做法,因为某些外观可能不支持不确定模式。
你适合学Java吗?4大专业测评方法
代码逻辑 吸收能力 技术学习能力 综合素质
先测评确定适合在学习