SwingWork + 執行緒池 +JTable +java寫入中文亂碼-- 一個swing的小應用
阿新 • • 發佈:2019-02-12
這幾天因為業務需求需要開發一個批量訂購業務的小工具,之前一直是通過程式碼處理,想著做個圖形介面的小工具會更方便點
於是用swing做了這個小工具。因為需要http請求訂購介面,所以使用了swing中的執行緒工具SwingWork,這個類的用法和安卓的非同步訊息處理比較類似,同樣是開啟執行緒執行後臺任務,並能將處理結果更新到UI。 這個小應用裡是將http請求訂購介面後返回的訂購結果實時的更新到swing的JTable中
因為批量訂購資料量較大,所以使用了執行緒池
最後判斷執行緒池中所有任務是否執行完畢,並用IO流生成訂購日誌。注意對寫入中文亂碼的處理
比較簡單,介面比較醜~~ 直接上原始碼
匯入要處理的檔案格式: (訂購介面需要的引數)public class ServiceOrder extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; private ExecutorService pool; JLabel info; JTextField fileName; JButton improt; JButton open; JButton start; JTextArea count; JTextArea errort;; JTable table; JScrollPane scrollPane; DefaultTableModel defaultModel; JPanel j1; JPanel j2; JPanel j3; JPanel j4; JPanel j5; JFileChooser filechoose = new JFileChooser(); FileFilter filter; Vector<String> head; // 定義異常訂購資料總數 int errorcount = 0; //定義一次匯入處理完成標識(匯入處理完成後不能開始處理第二次,除非重新匯入) boolean ordered =false; public ServiceOrder() { j1 = new JPanel(); j1.setPreferredSize(new Dimension(700, 30)); FlowLayout fl1 = new FlowLayout(FlowLayout.CENTER, 10, 10); j1.setLayout(fl1); info = new JLabel("匯入要處理的賬號"); j1.add(info); j2 = new JPanel(); j2.setPreferredSize(new Dimension(700, 50)); FlowLayout fl2 = new FlowLayout(FlowLayout.CENTER, 10, 10); j2.setLayout(fl2); fileName = new JTextField(40); improt = new JButton("匯入"); open = new JButton("開啟"); open.addActionListener(this); improt.addActionListener(this); j2.add(fileName); j2.add(open); j2.add(improt); j3 = new JPanel(); j3.setPreferredSize(new Dimension(720, 380)); head = new Vector<String>(); head.add("賬號"); head.add("來源"); head.add("型別"); head.add("產品"); head.add("平臺"); head.add("處理結果"); head.add("處理時間"); defaultModel = new DefaultTableModel(null, head); table = new JTable(defaultModel); table.setPreferredScrollableViewportSize(new Dimension(700, 350)); scrollPane = new JScrollPane(table); this.getContentPane().add(scrollPane, BorderLayout.CENTER); j3.add(scrollPane); j4 = new JPanel(); j4.setPreferredSize(new Dimension(700, 30)); start = new JButton("開始"); start.addActionListener(this); FlowLayout fl4 = new FlowLayout(FlowLayout.CENTER); j4.setLayout(fl4); j4.add(start); j5 = new JPanel(); j5.setPreferredSize(new Dimension(700, 30)); j5.setLayout(fl1); count = new JTextArea(); errort = new JTextArea(); j5.add(count); j5.add(errort); FlowLayout fl5 = new FlowLayout(FlowLayout.CENTER); setLayout(fl5); add(j1); add(j2); add(j3); add(j5); add(j4); setTitle("批量訂購"); setSize(800, 620); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); // 設定開啟檔案/ filechoose.setFileSelectionMode(JFileChooser.FILES_ONLY);// 設定選擇模式,只可以選擇檔案 String extj[] = { "txt" }; filter = new FileNameExtensionFilter("txt", extj); filechoose.setFileFilter(filter);// 設定檔案字尾過濾器 } public static void main(String[] args) { new ServiceOrder(); } @Override public void actionPerformed(ActionEvent e) { int retval; String selection = e.getActionCommand(); if (selection.equals("開啟")) { retval = filechoose.showOpenDialog(this);// 顯示"儲存檔案"對話方塊 if (retval == JFileChooser.APPROVE_OPTION) {// 若成功開啟 File file = filechoose.getSelectedFile();// 得到選擇的檔案 fileName.setText(file.getPath()); // 清空表格資料 while (defaultModel.getRowCount() > 0) { defaultModel.removeRow(defaultModel.getRowCount() - 1); } count.setText(""); errort.setText(""); } } else if (selection.equals("匯入")) { ordered =false; errorcount = 0; errort.setText(""); String name = fileName.getText(); File file = new File(name); if (DateUtils.isBlank(name) || !file.exists()) { JOptionPane.showMessageDialog(ServiceOrder.this, "沒有選擇檔案或檔案不存在", "提示", JOptionPane.ERROR_MESSAGE); } else { // 匯入之前清空表格資料 while (defaultModel.getRowCount() > 0) { defaultModel.removeRow(defaultModel.getRowCount() - 1); } FileReader fileReader; try { fileReader = new FileReader(file); BufferedReader bufferedReader = new BufferedReader( fileReader); int lineCount = 0; String line = null; while ((line = bufferedReader.readLine()) != null) { if (DateUtils.isNotBlank(line)) { String[] temps = line.split("\\|"); Vector<String> row = new Vector<String>(); row.add(temps[0].trim()); row.add(temps[1].trim()); row.add(temps[2].trim()); row.add(temps[3].trim()); row.add(temps[4].trim()); defaultModel.addRow(row); lineCount++; } } fileReader.close(); bufferedReader.close(); count.setText("共匯入" + lineCount + "條資料"); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } } } else if (selection.equals("開始")) { pool = Executors.newFixedThreadPool(5);//初始化執行緒池 if(!ordered){ Vector<Vector<String>> data = defaultModel.getDataVector(); if (data == null) { JOptionPane.showMessageDialog(ServiceOrder.this, "沒有要處理的資料", "提示", JOptionPane.ERROR_MESSAGE); } else { start.setText("正在處理"); start.setEnabled(false); improt.setEnabled(false); open.setEnabled(false); fileName.setVisible(false); for (int i = 0; i < data.size(); i++) { final int j = i; // 多執行緒發起訂購 pool.execute(new SwingWorker<String[], Void>() { @Override protected String[] doInBackground() throws Exception { // 發起訂購 JSONObject resultinfo = OrderClient.order(data .get(j)); String results = ""; if (resultinfo == null) { results = "處理異常"; synchronized (this) { errorcount++; } } else { if ("0".equals(resultinfo.getString("result"))) { results = "成功"; } else { results = "失敗!錯誤碼" + resultinfo.getString("result"); } } String time = DateUtils.formatString(new Date(), DateUtils.DATE_FORMAT_YMDHMS); String[] temps = new String[3]; temps[0] = results; temps[1] = time; temps[2] = j + ""; return temps; } @Override protected void done() { // 獲得doInBackground()返回資料 String[] result = null; try { result = get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } // 處理結果更新到表格 defaultModel.setValueAt(result[0], Integer.valueOf(result[2]), 5); defaultModel.setValueAt(result[1], Integer.valueOf(result[2]), 6); } }); } // 新增所有任務處理完成監聽 success(); } }else{ JOptionPane.showMessageDialog(ServiceOrder.this, "匯入資料已處理完成,請重新匯入", "提示", JOptionPane.ERROR_MESSAGE); } } } // 判斷是否所有任務都執行完成,生成處理日誌 private void success() { pool.shutdown(); SwingWorker<String, Void> work = new SwingWorker<String, Void>() { @Override protected String doInBackground() throws Exception { while (true) { if (pool.isTerminated()) { break; } Thread.sleep(1000); } // 生成訂購結果日誌 BufferedWriter bufferedWriter = null; try { File f = new File(fileName.getText() + "_log_" + DateUtils.formatString(new Date(), DateUtils.DATE_FORMATE_LX_YMDHMS) + ".txt"); if (!f.exists()) { f.createNewFile(); } bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f),"GBK")); bufferedWriter .write("userid | uoid | action | productId |desc | result | addtime"); bufferedWriter.newLine(); Vector<Vector<String>> data = defaultModel.getDataVector(); for (Vector<String> vector : data) { bufferedWriter.write(vector.get(0) + "|" + vector.get(1) + "|" + vector.get(2) + "|" + vector.get(3) + "|" + vector.get(4) + "|" +vector.get(5) + "|" + vector.get(6)); bufferedWriter.newLine(); } } catch (IOException e1) { e1.printStackTrace(); } finally { try { if (bufferedWriter != null) { bufferedWriter.flush(); bufferedWriter.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return null; } @Override protected void done() { JOptionPane.showMessageDialog(ServiceOrder.this, "處理完成!", "提示", JOptionPane.ERROR_MESSAGE); errort.setText(" 處理異常共" + errorcount + "條"); start.setText("開始"); start.setEnabled(true); improt.setEnabled(true); open.setEnabled(true); fileName.setVisible(true); ordered= true;//標識一次匯入處理完成 } }; work.execute(); } }
0000000412|9999|1|000011|HUYYU
0000000413|9999|1|000000|HUIUIIU
生成的訂購日誌:
userid | uoid | action | productId |desc| result | addtime
0000000412|9999|1|000001|HUYYU|失敗!錯誤碼501|2015-11-23 10:53:43
0000000413|9999|1|000000|HUIUIIU|失敗!錯誤碼501|2015-11-23 10:53:43