28.3. Layout Managers

 

[Page 805 ( continued )]

24.18. (Optional) JProgressBar

JProgressBar is a component that displays a value graphically within a bounded interval. A progress bar is typically used to show the percentage of completion of a lengthy operation; it comprises a rectangular bar that is "filled in" from left to right horizontally or from bottom to top vertically as the operation is performed. It provides the user with feedback on the progress of the operation. For example, when a file is being read, it alerts the user to the progress of the operation, thereby keeping the user attentive.

JProgressBar is often implemented using a thread to monitor the completion status of other threads. The progress bar can be displayed horizontally or vertically, as determined by its orientation property. The minimum , value , and maximum properties determine the minimum, current, and maximum lengths on the progress bar, as shown in Figure 24.28. Figure 24.29 lists frequently used features of JProgressBar .

Figure 24.28. JProgressBar displays the progress of a task.


Figure 24.29. JProgressBar is a Swing component with many properties that enable you to customize a progress bar.
(This item is displayed on page 806 in the print version)

To demonstrate JProgressBar , let us write a GUI application that copies files. A progress bar is used to show the progress of the copying operation, as shown in Figure 24.30.

Figure 24.30. The user enters the files in the text fields and clicks the Copy button to start copying files.
(This item is displayed on page 806 in the print version)


Place a JProgressBar in the north of the frame. Place a button in a panel, and place the panel in the south of the frame. Place the two text fields in two panels, set the titles on the borders of the panels, and place the panels in another panel of the GridLayout with two rows. Place the panel in the center of the frame.


[Page 806]

While copying the data from a source file to a destination file on one thread, the progress bar is updated on another thread. You need to create a thread that copies a file and another thread that updates the progress bar. Every time some bytes of the file are copied , the current value in the progress bar is updated to show the progress.

Create a main class named CopyFile that lays out the user interface. Declare an inner class named CopyFileTask that implements Runnable to copy files. When the Copy button is pressed, a thread for copying a file is created and started in line 41. The progress bar is updated in line 87 as a file is being copied. The complete program is given in Listing 24.13.

Listing 24.13. CopyFile.java
(This item is displayed on pages 806 - 808 in the print version)
1


import


java.awt.*; 2


import


java.awt.event.*; 3


import


javax.swing.*; 4


import


javax.swing.border.*; 5


import


java.io.*; 6 7


public class


CopyFile


extends


JFrame { 8


private


JProgressBar jpb =


new


JProgressBar();

[Page 807]
9


private


JButton jbtCopy =


new


JButton(


"Copy"


); 10


private


JTextField jtfFrom =


new


JTextField(); 11


private


JTextField jtfTo =


new


JTextField(); 12 13


public


CopyFile() { 14 JPanel jPanel2 =


new


JPanel(); 15 jPanel2.setLayout(


new


BorderLayout()); 16 jPanel2.setBorder(


new


TitledBorder(


"From"


)); 17 jPanel2.add(jtfFrom, BorderLayout.CENTER); 18 19 JPanel jPanel3 =


new


JPanel(); 20 jPanel3.setLayout(


new


BorderLayout()); 21 jPanel3.setBorder(


new


TitledBorder(


"To"


)); 22 jPanel3.add(jtfTo, BorderLayout.CENTER); 23 24 JPanel jPanel1 =


new


JPanel(); 25 jPanel1.setLayout(


new


GridLayout(


2


,


1


)); 26 jPanel1.add(jPanel2); 27 jPanel1.add(jPanel3); 28 29 JPanel jPanel4 =


new


JPanel(); 30 jPanel4.add(jbtCopy); 31 32


this


.add(jpb, BorderLayout.NORTH); 33


this


.add(jPanel1, BorderLayout.CENTER); 34


this


.add(jPanel4, BorderLayout.SOUTH); 35 36 jpb.setStringPainted(


true


);

// Paint the percent in a string

37 38 jbtCopy.addActionListener(


new


ActionListener() { 39


public void


actionPerformed(ActionEvent e) { 40

// Create a thread for copying files

41


new


Thread(


new


CopyFileTask()).start(); 42 } 43 }); 44 } 45 46


public static void


main(String[] args) { 47 CopyFile frame =


new


CopyFile(); 48 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 49 frame.setTitle(


"CopyFile"


); 50 frame.setSize(


400


,


180


); 51 frame.setVisible(


true


); 52 } 53 54

// Copy file and update progress bar in a separate thread

55


class


CopyFileTask


implements


Runnable { 56


private int


currentValue; 57 58


public void


run() { 59 BufferedInputStream in =


null


; 60 BufferedOutputStream out =


null


; 61


try


{ 62

// Create file input stream

63 File inFile =


new


File(jtfFrom.getText().trim()); 64 in =


new


BufferedInputStream(


new


FileInputStream(inFile)); 65 66

// Create file output stream

67 File outFile =


new


File(jtfTo.getText()); 68 out =


new


BufferedOutputStream(


new


FileOutputStream(outFile));

[Page 808]
69 70

// Get total bytes in the file

71


long


totalBytes = in.available(); 72 73

// Start progress meter bar

74 jpb.setValue(




); 75 jpb.setMaximum(


100


); 76 77


int


r; 78


long


bytesRead =




; 79

// You may increase buffer

size

to improve IO speed

80


byte


[] b =


new byte


[


10


]; 81


while


((r = in.read(b,




, b.length)) !=


-1


) { 82 out.write(b,




, r); 83 bytesRead += r; 84 currentValue = (


int


)(bytesRead *


100


/ totalBytes); 85 86

// Update the progress bar

87 jpb.setValue(currentValue); 88 } 89 } 90


catch


(FileNotFoundException ex) { 91 ex.printStackTrace(); 92 } 93


catch


(IOException ex) { 94 ex.printStackTrace(); 95 } 96


finally


{ 97


try


{ 98


if


(in !=


null


) in.close(); 99


if


(out !=


null


) out.close(); 100 } 101


catch


(Exception ex) {} 102 } 103 } 104 } 105 }

{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}

The class CopyFileTask is a task class. The program creates a task for copying a file on a separate thread. What would happen if copying a file is not run on a separate thread? The progress bar will not be updated until the copy ends. This is because the operation for repainting the progress bar runs on the thread with the actionPerformed method. As long as the copy operation continues, the progress bar never gets a chance to be repainted. Running the copy operation on a separate thread will enable the progress bar to be repainted simultaneously with the copy operation.