Java Tutorial/Swing/SwingWorker
Содержание
14. extends generic SwingWorker
<source lang="java">
/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Sun Microsystems nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; import java.util.Random; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import javax.swing.border.Border; public class Flipper extends JFrame implements ActionListener {
private final GridBagConstraints constraints; private final JTextField headsText, totalText, devText; private final Border border = BorderFactory.createLoweredBevelBorder(); private final JButton startButton, stopButton; private FlipTask flipTask; private JTextField makeText() { JTextField t = new JTextField(20); t.setEditable(false); t.setHorizontalAlignment(JTextField.RIGHT); t.setBorder(border); getContentPane().add(t, constraints); return t; } private JButton makeButton(String caption) { JButton b = new JButton(caption); b.setActionCommand(caption); b.addActionListener(this); getContentPane().add(b, constraints); return b; } public Flipper() { super("Flipper"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Make text boxes getContentPane().setLayout(new GridBagLayout()); constraints = new GridBagConstraints(); constraints.insets = new Insets(3, 10, 3, 10); headsText = makeText(); totalText = makeText(); devText = makeText(); // Make buttons startButton = makeButton("Start"); stopButton = makeButton("Stop"); stopButton.setEnabled(false); // Display the window. pack(); setVisible(true); } private static class FlipPair { private final long heads, total; FlipPair(long heads, long total) { this.heads = heads; this.total = total; } } private class FlipTask extends SwingWorker<Void, FlipPair> { @Override protected Void doInBackground() { long heads = 0; long total = 0; Random random = new Random(); while (!isCancelled()) { total++; if (random.nextBoolean()) { heads++; } publish(new FlipPair(heads, total)); } return null; } @Override protected void process(List<FlipPair> pairs) { FlipPair pair = pairs.get(pairs.size() - 1); headsText.setText(String.format("%d", pair.heads)); totalText.setText(String.format("%d", pair.total)); devText.setText(String.format("%.10g", ((double) pair.heads) / ((double) pair.total) - 0.5)); } } public void actionPerformed(ActionEvent e) { if ("Start" == e.getActionCommand()) { startButton.setEnabled(false); stopButton.setEnabled(true); (flipTask = new FlipTask()).execute(); } else if ("Stop" == e.getActionCommand()) { startButton.setEnabled(true); stopButton.setEnabled(false); flipTask.cancel(true); flipTask = null; } } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new Flipper(); } }); }
}</source>
14. Progress Monitor and Swingworker
<source lang="java">
/*
* Copyright (c) 1995 - 2008 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Sun Microsystems nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
import java.awt.BorderLayout; import java.awt.Insets; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Random; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.ProgressMonitor; import javax.swing.SwingWorker; public class ProgressMonitorDemo extends JPanel implements ActionListener,
PropertyChangeListener { private ProgressMonitor progressMonitor; private JButton startButton; private JTextArea taskOutput; private Task task; class Task extends SwingWorker<Void, Void> { @Override public Void doInBackground() { Random random = new Random(); int progress = 0; setProgress(0); try { Thread.sleep(1000); while (progress < 100 && !isCancelled()) { // Sleep for up to one second. Thread.sleep(random.nextInt(1000)); // Make random progress. progress += random.nextInt(10); setProgress(Math.min(progress, 100)); } } catch (InterruptedException ignore) { } return null; } @Override public void done() { Toolkit.getDefaultToolkit().beep(); startButton.setEnabled(true); progressMonitor.setProgress(0); } } public ProgressMonitorDemo() { super(new BorderLayout()); // Create the demo"s UI. startButton = new JButton("Start"); startButton.setActionCommand("start"); startButton.addActionListener(this); taskOutput = new JTextArea(5, 20); taskOutput.setMargin(new Insets(5, 5, 5, 5)); taskOutput.setEditable(false); add(startButton, BorderLayout.PAGE_START); add(new JScrollPane(taskOutput), BorderLayout.CENTER); setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); } /** * Invoked when the user presses the start button. */ public void actionPerformed(ActionEvent evt) { progressMonitor = new ProgressMonitor(ProgressMonitorDemo.this, "Running a Long Task", "", 0, 100); progressMonitor.setProgress(0); task = new Task(); task.addPropertyChangeListener(this); task.execute(); startButton.setEnabled(false); } /** * Invoked when task"s progress property changes. */ public void propertyChange(PropertyChangeEvent evt) { if ("progress" == evt.getPropertyName()) { int progress = (Integer) evt.getNewValue(); progressMonitor.setProgress(progress); String message = String.format("Completed %d%%.\n", progress); progressMonitor.setNote(message); taskOutput.append(message); if (progressMonitor.isCanceled() || task.isDone()) { Toolkit.getDefaultToolkit().beep(); if (progressMonitor.isCanceled()) { task.cancel(true); taskOutput.append("Task canceled.\n"); } else { taskOutput.append("Task completed.\n"); } startButton.setEnabled(true); } } } /** * Create the GUI and show it. For thread safety, this method should be * invoked from the event-dispatching thread. */ private static void createAndShowGUI() { // Create and set up the window. JFrame frame = new JFrame("ProgressMonitorDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Create and set up the content pane. JComponent newContentPane = new ProgressMonitorDemo(); newContentPane.setOpaque(true); // content panes must be opaque frame.setContentPane(newContentPane); // Display the window. frame.pack(); frame.setVisible(true); } public static void main(String[] args) { // Schedule a job for the event-dispatching thread: // creating and showing this application"s GUI. javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } }); }
}</source>
14. SwingWorker in Java 6
<source lang="java">
import java.awt.LayoutManager; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.List; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.SwingWorker; public class Main{
public static void main(String[] args) { final JProgressBar progressBar = new JProgressBar(0, 10); final CounterTask task = new CounterTask(); task.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if ("progress".equals(evt.getPropertyName())) { progressBar.setValue((Integer) evt.getNewValue()); } } }); JButton startButton = new JButton("Start"); startButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { task.execute(); } }); JButton cancelButton = new JButton("Cancel"); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { task.cancel(true); } }); JPanel buttonPanel = new JPanel(); buttonPanel.add(startButton); buttonPanel.add(cancelButton); JPanel cp = new JPanel(); LayoutManager layout = new BoxLayout(cp, BoxLayout.Y_AXIS); cp.setLayout(layout); cp.add(buttonPanel); cp.add(progressBar); JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setContentPane(cp); frame.pack(); frame.setVisible(true); }
} class CounterTask extends SwingWorker<Integer, Integer> {
int DELAY = 1000; @Override protected Integer doInBackground() throws Exception { int i = 0; int count = 10; while (!isCancelled() && i < count) { i++; publish(new Integer[] { i }); setProgress(count * i / count); Thread.sleep(DELAY); } return count; } protected void process(List<Integer> chunks) { System.out.println(chunks); } @Override protected void done() { if (isCancelled()) System.out.println("Cancelled !"); else System.out.println("Done !"); }
}</source>
14. Use SwingWorker to perform background tasks
<source lang="java">
import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.SwingWorker; public class Main extends JFrame {
public Main() { this.setLayout(new FlowLayout()); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JButton processButton = new JButton("Start"); JButton helloButton = new JButton("Hello"); processButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { MyTask process = new MyTask(); try { process.execute(); } catch (Exception e) { e.printStackTrace(); } } }); helloButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(null, "Hello There"); } }); this.getContentPane().add(processButton); this.getContentPane().add(helloButton); this.pack(); setVisible(true); } public static void main(String[] args) { new Main(); }
} class MyTask extends SwingWorker {
protected Object doInBackground() throws Exception { Integer result = new Integer(0); for (int i = 0; i < 10; i++) { result += i * 10; try { Thread.sleep(5000); } catch (Exception e) { e.printStackTrace(); } } return result; }
}</source>