这几天因为业务需求需要开发一个批量订购业务的小工具,之前一直是通过代码处理,想着做个图形界面的小工具会更方便点
于是用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