在對大文件操作時,可能會需要些時間,此時為用戶提供進度條提示是非常常見的一項功能,這樣用戶就可以了解操作文件需要的時間信息。本實例為大家介紹了在復制大的文件時使用的進度條提示,需要注意的是,只有在讀取文件超過2秒時,才會顯示進度條。、
思路分析:
- 因為既要有操作面板又要有進度條,所以肯定要出現兩個繼承JFrame類的窗體。
- 先看被調用的進度條窗體,它不需要手動操作,所以類的內部實現一個方法就可以了。因為設計文件操作,所以要捕獲異常。首先根據要復制的文件創建File對象,以及根據復制后文件的保存地址創建File對象,然后創建FileOutputStream對象,再創建FileInputStream對象,之后是ProgressMonitorInputStream對象,然后讀取文件,如果總耗時超過2秒,將會自動彈出一個進度監視窗口。接下來定義byte數組,再使用while循環讀取文件,使用FileOutputStream類的write()方法通過流寫數據,再使用FileOutputStream類的close()方法關閉輸出流,最后使用ProgressMonitorInputStream類的close()方法關閉輸入流。可見該方法需要三個參數:彈出它的父窗口、要復制的文件地址以及要復制到的文件夾。
代碼如下:
ProgressMonitorTest.java:
package cn.edu.xidian.crytoll; import java.io.FileInputStream; import java.io.*; import javax.swing.JFrame; import javax.swing.ProgressMonitorInputStream; public class ProgressMonitorTest { public void useProgressMonitor(JFrame frame, String copyPath, String newPath) { try { File file = new File(copyPath); // 根據要復制的文件創建File對象 File newFile = new File(newPath); // 根據復制后文件的保存地址創建File對象 FileOutputStream fop = new FileOutputStream(newFile); // 創建FileOutputStream對象 InputStream in = new FileInputStream(file); // 讀取文件,如果總耗時超過2秒,將會自動彈出一個進度監視窗口。 ProgressMonitorInputStream pm = new ProgressMonitorInputStream( frame, "文件讀取中,請稍后...", in); int c = 0; byte[] bytes = new byte[1024]; // 定義byte數組 while ((c = pm.read(bytes)) != -1) { // 循環讀取文件 fop.write(bytes, 0, c); // 通過流寫數據 } fop.close(); // 關閉輸出流 pm.close(); // 關閉輸入流 } catch (Exception ex) { ex.printStackTrace(); } } }
3. 再看主窗體。JLabel、JTextField神馬的就不用說了,選擇文件和選擇文件夾這兩個按鈕也是老生常談了,最重要的是“開始復制”按鈕,將由它來負責彈出這個進度條,這就需要開辟一個新的線程,所以主窗體不僅要繼承JFrame類,還要實現Runnable接口。他大爺的。
4. 在開始復制按鈕的具體方法里,首先創建一個Thread對象作為新的線程,然后調用該對象的start()方法,重載執行run()方法,在該方法中創建一個進度條對象,使用JTextField類的getText()方法獲取要復制的文件地址和要復制到的路徑,然后調用進度條類里的方法。
代碼如下:
package cn.edu.xidian.crytoll; import java.awt.BorderLayout; import java.awt.Desktop; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.border.EmptyBorder; import javax.swing.filechooser.FileNameExtensionFilter; public class UserMonitorFrame extends JFrame implements Runnable{ /** * */ private static final long serialVersionUID = 8674569541853793419L; private JPanel contentPane; private JTextField fileField; private JTextField searchTextField; private JTextField replaceTextField; private File file; private JTextField textField; private JTextField textField_1; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { UserMonitorFrame frame = new UserMonitorFrame(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public UserMonitorFrame() { setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 501, 184); setTitle("在讀取文件時使用進度條"); getContentPane().setLayout(null); JLabel label = new JLabel("\u6587\u4EF6\u5730\u5740\uFF1A"); label.setBounds(10, 10, 70, 15); getContentPane().add(label); textField = new JTextField(); textField.setBounds(90, 7, 300, 21); getContentPane().add(textField); textField.setColumns(10); JButton button = new JButton("\u9009\u62E9\u6587\u4EF6"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { do_button_actionPerformed(e); } }); button.setBounds(400, 6, 93, 23); getContentPane().add(button); JLabel label_1 = new JLabel("\u590D\u5236\u5730\u5740\uFF1A"); label_1.setBounds(10, 40, 70, 15); getContentPane().add(label_1); textField_1 = new JTextField(); textField_1.setBounds(90, 38, 300, 21); getContentPane().add(textField_1); textField_1.setColumns(10); JButton button_1 = new JButton("\u9009\u62E9\u5730\u5740"); button_1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { do_button_1_actionPerformed(e); } }); button_1.setBounds(400, 39, 93, 23); getContentPane().add(button_1); JButton button_2 = new JButton("\u5F00\u59CB\u590D\u5236"); button_2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { do_copyButton_actionPerformed(e); } }); button_2.setBounds(182, 69, 93, 23); getContentPane().add(button_2); } protected void do_button_actionPerformed(ActionEvent e){ JFileChooser chooser=new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); // 顯示文件打開對話框 int option = chooser.showOpenDialog(this); // 確定用戶按下打開按鈕,而非取消按鈕 if (option != JFileChooser.APPROVE_OPTION) return; // 獲取用戶選擇的文件對象 file = chooser.getSelectedFile(); // 顯示文件信息到文本框 textField.setText(file.toString()); } protected void do_button_1_actionPerformed(ActionEvent e){ JFileChooser chooser=new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); int option=chooser.showOpenDialog(this); if(option!=JFileChooser.APPROVE_OPTION) return; file=chooser.getSelectedFile(); textField_1.setText(file.toString()); } //確定復制按鈕單擊事件 protected void do_copyButton_actionPerformed(ActionEvent arg0) { Thread thread = new Thread(this); thread.start(); } //應用多線程技術實現讀取操作 @Override public void run() { ProgressMonitorTest test = new ProgressMonitorTest(); String path = textField.getText(); String save = textField_1.getText(); test.useProgressMonitor(this,path,save+path.substring(path.lastIndexOf("."),path.length())); } }
效果如圖: