Java Swing中的SwingWorker

Swing中的SwingWorker主要是用来执行比较耗时的任务。

Java doc文档中中包含了一些简单的例子。

An abstract class to perform lengthy GUI-interaction tasks in a background thread. Several background threads can be used to execute such tasks. However, the exact strategy of choosing a thread for any particular SwingWorker is unspecified and should not be relied on.

When writing a multi-threaded application using Swing, there are two constraints to keep in mind: (refer to Concurrency in Swing for more details):
? Time-consuming tasks should not be run on the Event Dispatch Thread. Otherwise the application becomes unresponsive.
? Swing components should be accessed on the Event Dispatch Thread only.

These constraints mean that a GUI application with time intensive computing needs at least two threads: 1) a thread to perform the lengthy task and 2) the Event Dispatch Thread (EDT) for all GUI-related activities. This involves inter-thread communication which can be tricky to implement.

SwingWorker is designed for situations where you need to have a long running task run in a background thread and provide updates to the UI either when done, or while processing. Subclasses of SwingWorker must implement the doInBackground method to perform the background computation.

Workflow

There are three threads involved in the life cycle of a SwingWorker :

? Current thread: The execute method is called on this thread. It schedules SwingWorker for the execution on a worker thread and returns immediately. One can wait for the SwingWorker to complete using the get methods.

? Worker thread: The doInBackground method is called on this thread. This is where all background activities should happen. To notify PropertyChangeListeners about bound properties changes use the firePropertyChange and getPropertyChangeSupport methods. By default there are two bound properties available: state and progress.

? Event Dispatch Thread: All Swing related activities occur on this thread. SwingWorker invokes the process and done methods and notifies any PropertyChangeListeners on this thread.

Often, the Current thread is the Event Dispatch Thread.

Before the doInBackground method is invoked on a worker thread, SwingWorker notifies any PropertyChangeListeners about the state property change to StateValue.STARTED. After the doInBackground method is finished the done method is executed. Then SwingWorker notifies any PropertyChangeListeners about the state property change to StateValue.DONE.

SwingWorker is only designed to be executed once. Executing a SwingWorker more than once will not result in invoking the doInBackground method twice.

Sample Usage

The following example illustrates the simplest use case. Some processing is done in the background and when done you update a Swing component.

Say we want to find the "Meaning of Life" and display the result in a JLabel.

		final JLabel label;
		class MeaningOfLifeFinder extends SwingWorker<String, Object> {
			@Override
			public String doInBackground() {
				return findTheMeaningOfLife();
			}

			@Override
			protected void done() {
				try {
					label.setText(get());
				} catch (Exception ignore) {
				}
			}
		}

		(new MeaningOfLifeFinder()).execute();

The next example is useful in situations where you wish to process data as it is ready on the Event Dispatch Thread.

Now we want to find the first N prime numbers and display the results in a JTextArea. While this is computing, we want to update our progress in a JProgressBar. Finally, we also want to print the prime numbers to System.out.

class PrimeNumbersTask extends
SwingWorker<List<Integer>, Integer> {
PrimeNumbersTask(JTextArea textArea, int numbersToFind) {
//initialize
}

@Override
public List<Integer> doInBackground() {
while (! enough && ! isCancelled()) {
number = nextPrimeNumber();
publish(number);
setProgress(100 * numbers.size() / numbersToFind);
}
}
return numbers;
}

@Override
protected void process(List<Integer> chunks) {
for (int number : chunks) {
textArea.append(number + "\n");
}
}
}

JTextArea textArea = new JTextArea();
final JProgressBar progressBar = new JProgressBar(0, 100);
PrimeNumbersTask task = new PrimeNumbersTask(textArea, N);
task.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer)evt.getNewValue());
}
}
});

task.execute();
System.out.println(task.get()); //prints all prime numbers we have got

  

Because SwingWorker implements Runnable, a SwingWorker can be submitted to an java.util.concurrent.Executor for execution.
Parameters:<T> the result type returned by this SwingWorker‘s doInBackground and get methods<V> the type used for carrying out intermediate results by this SwingWorker‘s publish and process methodsSince:1.6Author:Igor Kushnirskiy

时间: 2024-10-27 01:44:27

Java Swing中的SwingWorker的相关文章

第二节 Java Swing中的基本容器:JFrame

第二节 基本容器:JFrame 如果要使用Swing创建一个窗口,则直接使用JFrame即可,此类事Component类的子类,常用方法如下: 小试牛刀 创建一个简单的窗口 import java.awt.*; import java.io.*; import javax.swing.*; public class JavaSwingTest { public static void main(String args[]) throws IOException{ test1(); } //创建一

Java Swing中有关事件机制

看到过两种方式启动主窗体的代码: 方式1: java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new MainJFrame().setVisible(true); } }); 方式2 javax.swing.SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new MainJFrame().setVisible(

java,swing中setvisible()使用注意事项

java中的setvisible(true)目的是使控件可以显示出来,如果该控件已经被显示出来,那么该方法是控件显示在窗口的最前方. 但其使用的位置需要注意.setVisible的对象一般是该对象的使用者调用的.如果setVisible在某个控件的内部,那么在setVisible函数后面添加的控件就显示不出来了. 原因就在于,setVisible(true)并不是告诉JVM让该控件可见,而是在内部调用repaint方法把各个控件画出来进行显示.如果在控件还没完全添加完其他控件就setVisibl

Java Swing中使用浏览器打开网址

使用浏览器打开网址 /////////////////////////////////////////////////////////     //  Bare Bones Browser Launch                          //     //  Version 3.1 (June 6, 2010)                         //     //  By Dem Pilafian                                   

Java Swing中Substance常用皮肤

AutumnSkin; BusinessSkin; BusinessBlackSteelSkin; BusinessBlueSteelSkin; ChallengerDeepSkin; CremeSkin; CremeCoffeeSkin; EmeraldDuskSkin; FindingNemoSkin; FieldOfWheatSkin; GreenMagicSkin; MangoSkin; MagmaSkin; MistAquaSkin; MistSilverSkin; ModerateS

Java Swing中Substance个人比较喜欢的两种组合

try { // 设置外形装饰为可装饰 JFrame.setDefaultLookAndFeelDecorated(true); // 设置外观 UIManager.setLookAndFeel(new SubstanceBusinessBlackSteelLookAndFeel()); // 设置主题 SubstanceLookAndFeel.setCurrentTheme(new SubstanceBottleGreenTheme()); // 设置皮肤 SubstanceLookAndFe

java swing中利用PS绘制漂亮的图形界面

首先从网上下载一些漂亮的界面:例如:要制作一个五子棋,那么就可以利用下面这个图形界面. 通过对鼠标位置的监听(主要是获取坐标)而实现不同的功能. 为界面添加鼠标监听: public class MyPicture extends JFrame implements MouseListener{} 从而获取坐标数据: public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub x=e.getX(); y=e

java swing制作右键菜单

java swing中如何实现右键菜单呢? 直接上代码: /*** java * 设置弹出菜单 * @param qrResultLabel */ private void setPopupMenu(JComponent qrResultLabel) { final MyMenuActionListener myMenuListener=new MyMenuActionListener(this); qrResultLabel.addMouseListener(new MouseInputAda

Java Swing界面编程(5)---JLabel中设置图片

package com.beyole.util; import java.awt.Color; import java.io.File; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; public class test4 { public static void main(String[] args) { JFrame fra