用SwingWorker实现程序的启动

由于Swing程序是非线程安全,所以界面控件相关的代码的创建和更新都要放在EDT线程内,因此我们常会把界面创建的代码放在SwingUtilities里,就像如下的代码:
SwingUtilities.invokeLater(new Runnable()
		{
			public void run()
			{
				JFrame frame = new JFrame();
				// ...相关的界面创建代码
				frame.setVisible(true);
			}
		});


如果只是写个小品级的程序的话这样就已经够了,但对于大型的程序来说这样做并不理想,很多程序在运行之初并不是先要创建界面而是要运行一些配置程序或连接数据库,而且这些前期的程序有时会返回一些中间结果,所以还需要一个启动界面来显示这些中间结果,直到这些前期程序运行完毕后轮到程序的主界面程序的创建和显示。但如果只是把这些前期程序写在SwingUtilities.invokeLater之前的反而会使界面创建和前期程序同时运行,结果往往是前期程序尚未完成,界面就已经创建完成并显示出了。对于这个问题可以使用SwingWorker类来解决。

SwingWorker类必须运行在EDT线程中。SwingWorker运行过程大致会为三个环节,首先在运行SwingWorker类的doInBackground方法,这个方法是在一个非EDT线程上运行的,运行的过程中可以通过SwingWorker类的publish方法来发布中间结果,并由process方法接收,process方法是运行在EDT线程上的所以可以在这个方法里创建启动界面并用于显示中间结果,直到doInBackground方法运行完毕后SwingWorker会再去调用done方法,这个方法也是运行EDT线程上,所以程序的主界面的创建和显示就在这里运行了。

下面给出代码说明:
public class ManagerCenter
{
	public static void main(String[] args)
	{
		new ManagerCenter();
	}

	SwingWorker worker = null; // 自定义启动界面
	StartDialog startDialog = null;

	public ManagerCenter()
	{

		// 泛型中的ManagerCenter类是doInBackground运行完毕后要返回的,
		// String是中间值
		worker = new SwingWorker<ManagerCenter, String>()
		{
			protected ManagerCenter doInBackground() throws Exception
			{
				ManagerCenter center = new ManagerCenter();
				this.publish("载入配置文件!"); // 用publish发布中间结果
				center.getConfig();
				this.publish("连接数据库!");
				center.connectionDataBase();
				return center;
			}

			protected void process(java.util.List<String> chunks)
			{
				for (String message : chunks)
				{
					if (startDialog == null)
						startDialog = new StartDialog();
					startDialog.setMessage(message);
				}
			};

			protected void done()
			{
				try
				{
					startDialog.dispose(); // 关闭启动界面
					// get()方法接收的就是doInBackground方法的结果
					new MainFrame(this.get());
				}
				catch (InterruptedException | ExecutionException e)
				{
					e.printStackTrace();
				}
			};
		};
		// 启动EDT线程
		SwingUtilities.invokeLater(new Runnable()
		{
			public void run()
			{
				worker.execute();
			}
		});
	}

	protected void connectionDataBase()
	{
		// TODO Auto-generated method stub
		
	}

	protected void getConfig()
	{
		// TODO Auto-generated method stub
		
	}
}


你可能感兴趣的:(用SwingWorker实现程序的启动)