1. 程式人生 > >java中的進度條的顯示

java中的進度條的顯示

     最近需要用到進度條,於是就查看了一下oracle的文件,看了一下java中進度條的顯示方法,現在就總結一下。

      java提供了三種關於進度條的顯示類。

   那麼這三種之間有什麼區別呢?下面我進行一下簡單的介紹,並提供例子方便大家理解。

JprogressBar

       作為一個元件,顯示 當前完成了多少工作。

ProgressMonitor

      這個不能作為一個元件顯示,他會彈出一個框,在框裡面來顯示進度。

ProgressMonitorInputStream

   這個從名字就看出來了這個類的作用了,就是將這個輸入流通過progressMonitorInputStream包裝,然後通過呼叫getProgressMonitor
可以檢視進度。


     咱們主要用的就是前兩個,所有我再次介紹一下前兩種方法。其實JprogressBar和ProgressMonitor的原理都是一樣的。首先建立一個類繼承SwingWorker,這個類的功能主要有三個:

  1:他會在doInBackground這個方法裡面,執行你所需要乾的事情。這個方法會開啟一個執行緒,這樣的使用者就不會在此阻塞而幹不了其他的事情了。

  2:當這個任務結束的時候,會呼叫done方法,你可以在這裡面寫入自己的實現。例如,彈出一個框顯示任務結束。

  3:有一個int型別的變數progress,這個變數就是顯示任務的執行進度,每次progress改變的時候,propertyChange

這個方法就會被呼叫。

    這樣思路就更加清晰了,首先建立的類A繼承SwingWorker,在doInBackground這個方法裡面寫上你需要顯示進度的任務,並在適當的時候通過呼叫setProgress(value)方法改變progress這個值,value代表任務進行到多少了,最少是0,最大是100(代表任務結束了),當然使用者也可以自己進行設定最小最大值。如果有需要的話,也可以在done方法裡面寫上自己的實現。

   建立另外一個類B,這個類的作用就是通過進度條來顯示你的任務進行到哪個地步了。在類A當中提過了,在doInBackground中,使用者通過改變progress來表示任務執行的情況,所以只要當類A中的progress一改變我就把值得到,這個值就是當前任務的完成率,然後在類B中顯示到進度條上就可以了。所以我們要給類A中的progress新增一個監聽器,這個監聽器其實就是類B。因此B需要實現PropertyChangeListener這個介面,實現PropertyChange()這個方法.

  接下來要做的就是例項化類A,並新增監聽器,然後執行類A的任務就可以了。如下例:

import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.beans.*; import java.util.Random; public class ProgressBarDemo extends JPanel implements ActionListener, PropertyChangeListener { private JProgressBar progressBar; private JButton startButton; private JTextArea taskOutput; private Task task; class Task extends SwingWorker<Void, Void> { /* * Main task. Executed in background thread. */ @Override public Void doInBackground() { Random random = new Random(); int progress = 0; //Initialize progress property. setProgress(0); while (progress < 100) { //Sleep for up to one second. try { Thread.sleep(random.nextInt(1000)); } catch (InterruptedException ignore) {} //Make random progress. progress += random.nextInt(10); setProgress(Math.min(progress, 100)); } return null; } /* * Executed in event dispatching thread */ @Override public void done() { Toolkit.getDefaultToolkit().beep(); startButton.setEnabled(true); setCursor(null); //turn off the wait cursor taskOutput.append("Done!\n"); } } public ProgressBarDemo() { super(new BorderLayout()); //Create the demo's UI. startButton = new JButton("Start"); startButton.setActionCommand("start"); startButton.addActionListener(this); progressBar = new JProgressBar(0, 100); progressBar.setValue(0); progressBar.setStringPainted(true); taskOutput = new JTextArea(5, 20); taskOutput.setMargin(new Insets(5,5,5,5)); taskOutput.setEditable(false); JPanel panel = new JPanel(); panel.add(startButton); panel.add(progressBar); add(panel, BorderLayout.PAGE_START); add(new JScrollPane(taskOutput), BorderLayout.CENTER); setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); } /** * Invoked when the user presses the start button. */ public void actionPerformed(ActionEvent evt) { startButton.setEnabled(false); setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); //Instances of javax.swing.SwingWorker are not reusuable, so //we create new instances as needed. task = new Task(); task.addPropertyChangeListener(this); task.execute(); } /** * Invoked when task's progress property changes. */ public void propertyChange(PropertyChangeEvent evt) { if ("progress" == evt.getPropertyName()) { int progress = (Integer) evt.getNewValue(); progressBar.setValue(progress); taskOutput.append(String.format( "Completed %d%% of task.\n", task.getProgress())); } } /** * Create the GUI and show it. As with all GUI code, this must run * on the event-dispatching thread. */ private static void createAndShowGUI() { //Create and set up the window. JFrame frame = new JFrame("ProgressBarDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. JComponent newContentPane = new ProgressBarDemo(); newContentPane.setOpaque(true); //content panes must be opaque frame.setContentPane(newContentPane); //Display the window. frame.pack(); frame.setVisible(true); } public static void main(String[] args) { //Schedule a job for the event-dispatching thread: //creating and showing this application's GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } } 這個是一個JProgressBar的例子,下面是一個ProgressMonitor的例子,讀者可以比較一下。 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.beans.*; import java.util.Random; public class ProgressMonitorDemo extends JPanel implements ActionListener, PropertyChangeListener { private ProgressMonitor progressMonitor; private JButton startButton; private JTextArea taskOutput; private Task task; class Task extends SwingWorker<Void, Void> { @Override public Void doInBackground() { Random random = new Random(); int progress = 0; setProgress(0); try { Thread.sleep(1000); while (progress < 100 && !isCancelled()) { //Sleep for up to one second. Thread.sleep(random.nextInt(1000)); //Make random progress. progress += random.nextInt(10); setProgress(Math.min(progress, 100)); } } catch (InterruptedException ignore) {} return null; } @Override public void done() { Toolkit.getDefaultToolkit().beep(); startButton.setEnabled(true); progressMonitor.setProgress(0); } } public ProgressMonitorDemo() { super(new BorderLayout()); //Create the demo's UI. startButton = new JButton("Start"); startButton.setActionCommand("start"); startButton.addActionListener(this); taskOutput = new JTextArea(5, 20); taskOutput.setMargin(new Insets(5,5,5,5)); taskOutput.setEditable(false); add(startButton, BorderLayout.PAGE_START); add(new JScrollPane(taskOutput), BorderLayout.CENTER); setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); } /** * Invoked when the user presses the start button. */ public void actionPerformed(ActionEvent evt) { progressMonitor = new ProgressMonitor(ProgressMonitorDemo.this, "Running a Long Task", "", 0, 100); progressMonitor.setProgress(0); task = new Task(); task.addPropertyChangeListener(this); task.execute(); startButton.setEnabled(false); } /** * Invoked when task's progress property changes. */ public void propertyChange(PropertyChangeEvent evt) { if ("progress" == evt.getPropertyName() ) { int progress = (Integer) evt.getNewValue(); progressMonitor.setProgress(progress); String message = String.format("Completed %d%%.\n", progress); progressMonitor.setNote(message); taskOutput.append(message); if (progressMonitor.isCanceled() || task.isDone()) { Toolkit.getDefaultToolkit().beep(); if (progressMonitor.isCanceled()) { task.cancel(true); taskOutput.append("Task canceled.\n"); } else { taskOutput.append("Task completed.\n"); } startButton.setEnabled(true); } } } /** * Create the GUI and show it.  For thread safety, * this method should be invoked from the * event-dispatching thread. */ private static void createAndShowGUI() { //Create and set up the window. JFrame frame = new JFrame("ProgressMonitorDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Create and set up the content pane. JComponent newContentPane = new ProgressMonitorDemo(); newContentPane.setOpaque(true); //content panes must be opaque frame.setContentPane(newContentPane); //Display the window. frame.pack(); frame.setVisible(true); } public static void main(String[] args) { //Schedule a job for the event-dispatching thread: //creating and showing this application's GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); } }

下面講一講我們什麼時候用JProgressBar,什麼時候用ProgressMonitor呢?

用到JProgressBar的時候

 1:當你需要對進度條進行更加細緻的控制的時候,比如給進度條新增事件等等。

 2:你需要顯示跟進度條有一定關聯關係的元件的時候。

 3:你需要同時顯示多個進度條。

 4:這個進度條可以重複使用的時候。

用ProgressMonitor的時候

 1:只是想在一個彈出框裡面簡單的顯示進度而已。

 2:這個任務不是很重要,使用者對此也不是很感興趣。基於此,ProgressMonitor還提供給了使用者cancel的按鈕。

 3:需要不定時得向用戶傳遞資訊(關於任務的資訊,例如下一步需要幹嘛)。