SwingWork + 线程池 +JTable +java写入中文乱码-- 一个swing的小应用

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


于是用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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JTable 和 Excel 图表是常被用在网格或表格中显示数据。通常,用户希望输入到 JTable 的数据已经存在于 Excel 电子表格中。Excel 格式使用在非 Excel 软件中来实现导入-导出功能。因为如此,Java 软件也应该提供通用的剪贴板功能,例如在 JTable 和 Excel 间复制和粘贴。本文展示了如何使用系统粘贴板在 Java 程序和 Excel 间复制数据。使用这一 Java 技巧中提供的适配器类,只需一行代码即可添加在 JTables 和 Excel 间复制和粘贴信息的功能。请注意,由于未签名的 applet 不能使用系统剪贴板,此功能不适用于这些 Java 程序。 当今很多业务应用程序都是使用 Java 开发的,并且以后这种用 Java 开发的应用会更多。而在许多应用程序都使用了 SwingJTable 组件,以类似电子表格的格式显示数据。如果业务应用程序可以将数据导入 Microsoft Excel 和从 Microsoft Excel 中导出数据,则会为用户带来方便,使用户可以使用无处不在的该电子表格程序的强大功能。此 Java 技巧将帮助您理解系统剪贴板,并使您的 JTable 能够与 Excel 交互和互操作。您将看到,通过在当前应用程序中仅仅添加另外的一行代码即可实现这一有用功能的添加。 要实现这一目标,需要做的只是复制这里给出的文件 ExcelAdapter.java,对其进行编译,并确保您的应用程序可以找到 ExcelAdapter.class 文件;做完后,JTable 就可以与 Excel 进行通话了!我们将向您展示仅通过这一行代码,如何实现到 Excel 的复制 (Ctrl+C) 和粘贴 (Ctrl+V) 以及从 Excel 进行的复制和粘贴。另外还提供了一个使用 ExcelAdapter 的示例应用程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值