Java核心技术(多线程)五
2011-04-21 11:14
387 查看
线程与Swing
使用线程是为了提高程序的响应性能。当程序需要做某些耗时的工作时,应该启动另一个工作器线程而不是阻塞用户接口。Swing不是线程安全的,如果你试图在多个线程中操纵用户界面的元素,那么用户界面可能崩溃。将线程与Swing一起使用时,必须遵循:*如果一个动作需要花费很长时间,在一个独立的工作器线程中做这件事不要在事件分配线程中做。
*除了事件分配线程,不要在任何线程中接触Swing组件。
应该使用EventQueue类的invokeLater和invokeAndWait方法使设置Swing界面的方法在事件分配线程中执行。invokeLater的方法立即返回,而run方法被异步执行;invokeAndWait方法等待直到run方法被确实执行过为止。
SwingWorker类是Swing工作器,是在专用线程中执行长时间GUI交互任务的抽象类。覆盖doInBackground方法来完成耗时的工作,不时地调用publish方法来报告工作进度。这一方法在工作器线程中执行。publish方法使得process方法在事件分配线程中执行来处理进度数据。当工作完成时,done方法在事件分配线程中被调用以便完成UI的更新。
public class SwingWorkerDemo { public static void main(String[] args) throws Exception { EventQueue.invokeLater(new Runnable() { public void run() { JFrame frame = new SwingWorkerFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }); } } class SwingWorkerFrame extends JFrame { public SwingWorkerFrame() { chooser = new JFileChooser(); chooser.setCurrentDirectory(new File(".")); textArea = new JTextArea(); add(new JScrollPane(textArea)); setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); statusLine = new JLabel(" "); add(statusLine, BorderLayout.SOUTH); JMenuBar menuBar = new JMenuBar(); setJMenuBar(menuBar); JMenu menu = new JMenu("File"); menuBar.add(menu); openItem = new JMenuItem("Open"); menu.add(openItem); openItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { int result = chooser.showOpenDialog(null); if (result == JFileChooser.APPROVE_OPTION) { textArea.setText(""); openItem.setEnabled(false); textReader = new TextReader(chooser.getSelectedFile()); textReader.execute(); cancelItem.setEnabled(true); } } }); cancelItem = new JMenuItem("Cancel"); menu.add(cancelItem); cancelItem.setEnabled(false); cancelItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { textReader.cancel(true); } }); } private class ProgressData { public int number; public String line; } private class TextReader extends SwingWorker<StringBuilder, ProgressData> { public TextReader(File file) { this.file = file; } public StringBuilder doInBackground() throws IOException, InterruptedException { int lineNumber = 0; Scanner in = new Scanner(new FileInputStream(file)); while (in.hasNextLine()) { String line = in.nextLine(); lineNumber++; text.append(line); text.append("/n"); ProgressData data = new ProgressData(); data.number = lineNumber; data.line = line; publish(data); Thread.sleep(1); } return text; } public void process(List<ProgressData> data) { if (isCancelled()) return; StringBuilder b = new StringBuilder(); statusLine.setText("" + data.get(data.size() - 1).number); for (ProgressData d : data) { b.append(d.line); b.append("/n"); } textArea.append(b.toString()); } public void done() { try { StringBuilder result = get(); textArea.setText(result.toString()); statusLine.setText("Done"); } catch (InterruptedException ex) { } catch (CancellationException ex) { textArea.setText(""); statusLine.setText("Cancelled"); } catch (ExecutionException ex) { statusLine.setText("" + ex.getCause()); } cancelItem.setEnabled(false); openItem.setEnabled(true); } private File file; private StringBuilder text = new StringBuilder(); }; private JFileChooser chooser; private JTextArea textArea; private JLabel statusLine; private JMenuItem openItem; private JMenuItem cancelItem; private SwingWorker<StringBuilder, ProgressData> textReader; public static final int DEFAULT_WIDTH = 450; public static final int DEFAULT_HEIGHT = 350; }
相关文章推荐
- Java 核心技术点之多线程
- Java多线程编程核心技术---单例模式与多线程
- java基础的核心技术:多线程(二)
- Java多线程编程核心技术 第一章笔记
- Java多线程编程核心技术(二)对象及变量的并发访问
- [JAVA]《Java 核心技术》(四)多线程
- Java多线程编程核心技术--Lock的使用(一)
- Java核心技术(多线程)二
- Java多线程核心技术(四):Lock的使用
- java核心技术-多线程基础
- [Java多线程编程核心技术]
- Java 多线程编程核心技术
- Java多线程编程核心技术---学习分享
- Java多线程编程核心技术--定时器
- Java多线程编程核心技术--定时器
- 多线程编程核心技术读书笔记(一):Java多线程技能
- Java多线程编程核心技术读书笔记(2)-并发控制
- 一、java多线程编程核心技术之(笔记)——多线程的实现
- java基础的核心技术:多线程(一)
- Java多线程编程核心技术---拾遗增补