最近在学习Swing,我们都知道在UI表现线程里面长时间执行操作时,画面会假死,为了能够让费时操作不影响画面表现,就需要用多线程了。首先考虑的就是Swing内部的 SwingWorkder对象,但是网上现成的例子不好找,主要参照了下面的URL,自己整理了一个。
http://d.hatena.ne.jp/nowokay/20081207/1228644742
注意:SwingWorkder对象只能执行一次,不能重复执行!例如点击开始,结束后,就不能再次开始了。
import java.awt.BorderLayout; import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.List; import java.util.concurrent.ExecutionException; import javax.swing.*; import javax.swing.SwingWorker; public class SwingWorkerSample { public static void main(String[] args) { // 外观定义 try { UIManager .setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); } catch (Exception ex) { } // 窗体 JFrame f = new JFrame("SwingWorker Sample"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 表示区 final JTextArea taOutput = new JTextArea(15, 30); JScrollPane sp = new JScrollPane(taOutput); f.add(sp); // 底部进度条 final JProgressBar progressBar = new JProgressBar(); f.add(BorderLayout.SOUTH, progressBar); // 开始按钮 JButton b = new JButton("开始"); f.add(BorderLayout.NORTH, b); // 结束按钮 JButton b2 = new JButton("结束"); f.add(BorderLayout.AFTER_LINE_ENDS, b2); // SwingWorker类 final SwingWorker<Integer, int[]> sw = new SwingWorker<Integer, int[]>() { /** 执行操作 */ @Override protected Integer doInBackground() throws Exception { int sum = 0; if (!this.isCancelled()) { for (int i = 1; i <= 10; ++i) { sum += i; publish(new int[] { i, sum });// 调用表示中间结果 setProgress(i * 10);// 进度条 Thread.sleep(1000); } } return sum; } /** 表示中间结果 */ @Override protected void process(List<int[]> chunks) { StringBuilder sb = new StringBuilder(); for (int[] values : chunks) { sb.append(String.format("累加%d等于%d%n", values[0], values[1])); } taOutput.append(sb.toString()); } /** 处理完成 */ @Override protected void done() { if (this != null && !this.isDone()) { try { int result = get(); taOutput.append("完了。 合计" + result + " "); } catch (InterruptedException ex) { } catch (ExecutionException ex) { } } } }; // 进度条表示 sw.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if ("progress".equals(evt.getPropertyName())) { progressBar.setValue((Integer) evt.getNewValue()); } } }); // 开始按钮事件 b.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { sw.execute();// 异步调用SwingWorkder } }); // 结束按钮 b2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (sw != null && !sw.isDone()) { // Cancel sw.cancel(true); } JOptionPane.showMessageDialog(null, "结束!"); } }); // 窗体表示 f.pack(); f.setVisible(true); } }