14.11 线程与Swing

来源:互联网 发布:广联达软件下载教程 编辑:程序博客网 时间:2024/05/29 09:15
import java.awt.*;import java.util.*;import javax.swing.*;/** * This program demonstrates that a thread that runs in parallel with the event * dispatch thread can cause errors in Swing components. * @version 1.24 2015-06-21 * @author Cay Horstmann */public class SwingThreadTest{   public static void main(String[] args)   {      EventQueue.invokeLater(() -> {         JFrame frame = new SwingThreadFrame();         frame.setTitle("SwingThreadTest");         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         frame.setVisible(true);      });   }}/** * This frame has two buttons to fill a combo box from a separate thread. The * "Good" button uses the event queue, the "Bad" button modifies the combo box * directly. */class SwingThreadFrame extends JFrame{   public SwingThreadFrame()   {      final JComboBox<Integer> combo = new JComboBox<>();      combo.insertItemAt(Integer.MAX_VALUE, 0);      combo.setPrototypeDisplayValue(combo.getItemAt(0));      combo.setSelectedIndex(0);      JPanel panel = new JPanel();      JButton goodButton = new JButton("Good");      goodButton.addActionListener(event ->         new Thread(new GoodWorkerRunnable(combo)).start());      panel.add(goodButton);      JButton badButton = new JButton("Bad");      badButton.addActionListener(event ->         new Thread(new BadWorkerRunnable(combo)).start());      panel.add(badButton);      panel.add(combo);      add(panel);      pack();   }}/** * This runnable modifies a combo box by randomly adding and removing numbers. * This can result in errors because the combo box methods are not synchronized * and both the worker thread and the event dispatch thread access the combo * box. */class BadWorkerRunnable implements Runnable{   private JComboBox<Integer> combo;   private Random generator;   public BadWorkerRunnable(JComboBox<Integer> aCombo)   {      combo = aCombo;      generator = new Random();   }   public void run()   {      try      {         while (true)         {            int i = Math.abs(generator.nextInt());            if (i % 2 == 0)               combo.insertItemAt(i, 0);            else if (combo.getItemCount() > 0)               combo.removeItemAt(i % combo.getItemCount());            Thread.sleep(1);         }      }      catch (InterruptedException e)      {      }   }}/** * This runnable modifies a combo box by randomly adding and removing numbers. * In order to ensure that the combo box is not corrupted, the editing * operations are forwarded to the event dispatch thread. */class GoodWorkerRunnable implements Runnable{   private JComboBox<Integer> combo;   private Random generator;   public GoodWorkerRunnable(JComboBox<Integer> aCombo)   {      combo = aCombo;      generator = new Random();   }   public void run()   {      try      {         while (true)         {            EventQueue.invokeLater(() ->                {                  int i = Math.abs(generator.nextInt());                  if (i % 2 == 0)                     combo.insertItemAt(i, 0);                  else if (combo.getItemCount() > 0)                     combo.removeItemAt(i % combo.getItemCount());               });            Thread.sleep(1);         }      }      catch (InterruptedException e)      {      }   }}
import java.awt.*;import java.io.*;import java.util.*;import java.util.List;import java.util.concurrent.*;import javax.swing.*;/** * This program demonstrates a worker thread that runs a potentially time-consuming task. * @version 1.11 2015-06-21 * @author Cay Horstmann */public class SwingWorkerTest{   public static void main(String[] args) throws Exception   {      EventQueue.invokeLater(() -> {         JFrame frame = new SwingWorkerFrame();         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         frame.setVisible(true);      });   }}/** * This frame has a text area to show the contents of a text file, a menu to open a file and  * cancel the opening process, and a status line to show the file loading progress. */class SwingWorkerFrame extends JFrame{   private JFileChooser chooser;   private JTextArea textArea;   private JLabel statusLine;   private JMenuItem openItem;   private JMenuItem cancelItem;   private SwingWorker<StringBuilder, ProgressData> textReader;   public static final int TEXT_ROWS = 20;   public static final int TEXT_COLUMNS = 60;   public SwingWorkerFrame()   {      chooser = new JFileChooser();      chooser.setCurrentDirectory(new File("."));      textArea = new JTextArea(TEXT_ROWS, TEXT_COLUMNS);      add(new JScrollPane(textArea));      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(event -> {            // show file chooser dialog            int result = chooser.showOpenDialog(null);            // if file selected, set it as icon of the label            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(event -> textReader.cancel(true));      pack();   }   private class ProgressData   {      public int number;      public String line;   }   private class TextReader extends SwingWorker<StringBuilder, ProgressData>   {      private File file;      private StringBuilder text = new StringBuilder();      public TextReader(File file)      {         this.file = file;      }      // The following method executes in the worker thread; it doesn't touch Swing components.      @Override      public StringBuilder doInBackground() throws IOException, InterruptedException      {         int lineNumber = 0;         try (Scanner in = new Scanner(new FileInputStream(file), "UTF-8"))         {            while (in.hasNextLine())                     {               String line = in.nextLine();               lineNumber++;               text.append(line).append("\n");               ProgressData data = new ProgressData();               data.number = lineNumber;               data.line = line;               publish(data);               Thread.sleep(1); // to test cancellation; no need to do this in your programs            }         }         return text;      }      // The following methods execute in the event dispatch thread.      @Override      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).append("\n");         textArea.append(b.toString());      }      @Override      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);      }   };}
0 0
原创粉丝点击