Merlin 的魔力: 不確定的進度條
JProgressBar 的一個細微但是重要的更新
級別: 初級
John Zukowski (jaz@zukowski.net), 總裁, JZ Ventures, Inc
2003 年 12 月 01 日
開發人員用 JProgressBar
組件向用戶顯示一項任務的進度。針對非常長的任務或者難于精確確定完成進度的任務,Merlin版本對 JProgressBar
增加了一個不確定模式。本月,專欄作者 John Zukowski 對 JProgressBar
的使用作了重新介紹,并討論了它的新的不確定模式。您可以在本文的 討論論壇中與作者以及其他讀者共享您的想法(您也可以單擊文章頂部或者底部的 討論進入論壇)。
在 Java 2 SDK, Standard Edition,版本 1.4 中,有了一些大的變化,如增加了像 JSpinner
這樣的新組件、像 SpringLayout
這樣的新布局管理器、或者像 Java Logging API 這樣的新 API。而另一些變化則沒有這么顯著,如小的改進或者對現有 API 的優化。本月關于 SpringLayout
組件的技巧就屬于后一種情況。它是細微的,但是很重要。
進度條的基本用法
JProgressBar
是原來的 Swing 組件集中的一個。它提供了一種以圖形方式顯示進程完成進度的簡單方式。當進程進行時,一個長條就會在該組件上逐漸延伸,直到任務完成并且長條全部填滿。長條的移動通常是某個多線程任務的一部分,這有助于避免阻塞應用程序其余部分的進度,如常規的屏幕更新。雖然沒有哪一條特定的規則說進度條必須進行線性移動,但是如果看到進程從 10% 移動到 35%,然后又回到 27%,然后再增加到 80%,最后以 0% 結束,作為用戶我會覺得多少有些古怪。
用五個構造函數中的一個來構造 JProgressBar
,如清單 1 所示:
清單 1. JProgressBar 構造函數
public JProgressBar()
public JProgressBar(int orientation)
public JProgressBar(int minimum, int maximum)
public JProgressBar(int orientation, int minimum, int maximum)
public JProgressBar(BoundedRangeModel model)
|
JProgressBar
需要初始化方向和值范圍。方向是通過 JProgressBar
的 VERTICAL
或者 HORIZONTAL
常量確定的。默認為 HORIZONTAL
。
在創建了這個組件并在屏幕上顯示它后,啟動第二個線程以執行需要測量其進度的任務。然后定期用 setValue()
方法更新進度條的值以顯示任務的當前進展。清單 2 顯示了 setValue()
的一個簡單例子:
清單 2. 簡單的 JProgressBar 使用方法
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.*;
public class ProgressSample {
static class BarThread extends Thread {
private static int DELAY = 500;
JProgressBar progressBar;
public BarThread(JProgressBar bar) {
progressBar = bar;
}
public void run() {
int minimum = progressBar.getMinimum();
int maximum = progressBar.getMaximum();
Runnable runner = new Runnable() {
public void run() {
int value = progressBar.getValue();
progressBar.setValue(value+1);
}
};
for (int i=minimum; i<maximum; i++) {
try {
SwingUtilities.invokeAndWait(runner);
// Our task for each step is to just sleep
Thread.sleep(DELAY);
} catch (InterruptedException ignoredException) {
} catch (InvocationTargetException ignoredException) {
}
}
}
}
public static void main(String args[]) {
// Initialize
final JProgressBar aJProgressBar = new JProgressBar(0, 100);
final JButton aJButton = new JButton("Start");
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
aJButton.setEnabled(false);
Thread stepper = new BarThread(aJProgressBar);
stepper.start();
}
};
aJButton.addActionListener(actionListener);
JFrame theFrame = new JFrame("Progress Bars");
theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = theFrame.getContentPane();
contentPane.add(aJProgressBar, BorderLayout.NORTH);
contentPane.add(aJButton, BorderLayout.SOUTH);
theFrame.setSize(300, 100);
theFrame.show();
}
}
|
第一次運行這段代碼時,您會看到類似于圖 1 的屏幕。
圖 1. 開始屏幕
單擊這個按鈕,啟動第二個任務,并在它運行時更新進度條。圖 2 顯示了運行到一半時的進度條。
圖 2. 屏幕顯示進度
這里沒什么特別的。主要代碼創建帶有一個按鈕和進度條的 GUI。當您選擇按鈕時,它就引發操作以更新進度條。進度條用來對某些任務進行測量。在示例程序中,這個任務就是休眠半秒 100 次。
在默認情況下,除了進度條外,沒有其他關于進度的圖形指示。添加如下的一行代碼,您就可以在任務完成過程中,讓進度條顯示任務完成的百分比:
aJProgressBar.setStringPainted(true);
|
圖 3 顯示了我們增加了新代碼的屏幕:
圖 3. 顯示完成百分比
使用不確定模式
從 Merlin 版本開始, JProgressBar
還支持另一種模式 ―― 確定。對于非固定步數的長任務,可以使用這種模式。它顯示固定的動畫以表明有些事情正在發生,但是它不表明完成的百分比。如果您確定了任務所要花費的時間,就可以切換回確定模式。在不確定模式下, JProgressBar
顯示一個長條,在顯示區域中來回移動。
清單 3 顯示了這種模式的一個例子。這個新方法就是 setIndeterminate()
。值為 true
意味著不確定,而值為 false
則意味著普通或者確定。
清單 3. 不確定進度條
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ProgressSample2 {
public static void main(String args[]) {
final JProgressBar aJProgressBar = new JProgressBar(0, 100);
aJProgressBar.setIndeterminate(true);
JButton aJButton = new JButton("Toggle");
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
boolean indeterminate = aJProgressBar.isIndeterminate();
aJProgressBar.setIndeterminate(!indeterminate);
}
};
aJButton.addActionListener(actionListener);
JFrame theFrame = new JFrame("Indeterminate");
theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = theFrame.getContentPane();
contentPane.add(aJProgressBar, BorderLayout.NORTH);
contentPane.add(aJButton, BorderLayout.SOUTH);
theFrame.setSize(300, 100);
theFrame.show();
}
}
|
圖 4顯示相關的屏幕(您需要想像這個長條是來回移動的)。按鈕用于在進度條的不確定和確定模式之間進行切換。
圖 4. 不確定模式
有兩種新的 UI 默認值用于改變重繪時間間隔和循環時間: ProgressBar.repaintInterval
和 ProgressBar.cycleTime
。改變這些設置 ―― 如下所示 ―― 會改變顯示速度。循環時間必須是重繪時間間隔的偶數倍,所以如果間隔為 100,那么循環時間應該是 200、500 或者 1000 ―― 但不能是 750。
UIManager.put("ProgressBar.repaintInterval", new Integer(150));
UIManager.put("ProgressBar.cycleTime", new Integer(1050));
|
注意您需要在創建進度條 之前設置這些值。
結束語
ProgressBar
還有很多內容,但是其他特性在 1.4 版中都沒有改變。我們簡單回顧了這個組件的原有使用方式,并介紹了在 Merlin 版本中它的新特性。您也可以考慮用 ProgressMonitor
或者 ProgressMonitorInputStream
監視這些長任務的進度。它們都在內部利用了 JProgressBar
的優點。
原文:http://www.ibm.com/developerworks/cn/java/j-mer11183/index.html
posted on 2007-11-07 09:54
lk 閱讀(448)
評論(0) 編輯 收藏 所屬分類:
j2se