`

Java Swing 常识篇 之 EDT

阅读更多


 Java Swing 常识篇之EDT

       从毕业到现在用SWING已经一年多,在这里想总结一下过去学到的东西和经验,和各位兄弟姐妹们一起分享。在以后的文章中也会和大家一起来分享一些好的框架。说起JAVA SWING,普遍给人的感觉是“丑、慢、难”,丑是界面丑、慢是速度慢、难是开发难。其实熟悉LAF的同学都知道SWING确实不丑;说到‘慢’,SWING也不慢,只要懂得如何处理长时间的TASK,而不是什么都在EDT处理;说到难,只要我们有一套自己专门开发SWINGUI的类库,也不难了。所以在接下来的文章中,我将会和大家构建一个SWING UI FRAMEWORK(暂时称为:Fast-DUI),在这个Fast-DUI中将会整合SWING中的动画(淡入淡出、滑上滑下)、效果(shadow、drop-shadow)、感官(LookAndFeel)等等。构建这样的一个框架主要是为了能够快速地开发出“漂亮的、用户体验好的”桌面应用程序。好了,接下来马上开始。今天的这篇文章在Swing的应用中起到举足轻重的作用。这篇文章是开头篇,可能写得不好,感觉自己的写作水平,和小学生有得一比。
        今天就一起来学习一下EDT(Event Dispatching Thread,字面上翻译成“事件分配线程”),那什么是EDT,EDT就简单地认为就是一个线程(特殊的线程),这个线程主要是管理着整个SWING GUI的事件,管理着整个UI界面(熟悉Java2D的朋友都知道,我们所看到的界面就是Java2D绘图绘出来的)。大家都知道,也许大学的时候,老师也会提到SWING不是线程安全的,不是线程安全的,那意味着我们用多线程的时候,要格外的小心,我们要把SWING里面东西的修改、获取独立放到一个线程上,但是这个刚好SWING的开发人员已经为我们解决了,我们不必自己管理一个额外的线程,我们只需要把他们放到EDT里面,下面我会举两个例子来说明一下如何使用EDT。
          第一个例子来讲一下如果不在EDT中修改Swing的东西会出现什么问题,请看下面的例子:

pakage org.dui.sample

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

/**
 * <code>NotInEDTSample</code> just demonstrates the usage of Swing EDT simply.
 * 
 * @author Jimmy.haung(SZ Team)
 * @since <i>DUI (Mar 25, 2013)</i>
 */
public class NotInEDTSample extends JFrame {
	private static final long serialVersionUID = 1L;
	private JTextField m_txt;

	public NotInEDTSample() {
		initGUI();
		notInEDT();
	}

	/**
	 * Init the GUI
	 */
	public void initGUI() {
		this.setTitle("a simple EDT Sample");
		m_txt = new JTextField();
		getContentPane().add(m_txt, BorderLayout.CENTER);
	}

	/**
	 * Process not under the EDT. 这里我启动了10个线程来改变<code>m_txt</code>的内容.
	 */
	private void notInEDT() {
		for (int i = 0; i < 4; ++i) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					while (true) {
						m_txt.setText("我不在EDT中操作!");
						try {
							Thread.sleep(100);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
				}
			}).start();
		}
	}

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				try {
					NotInEDTSample oFrame = new NotInEDTSample();
					oFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
					oFrame.setLocationRelativeTo(null);
					oFrame.setSize(300, 200);
					oFrame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

}

     运行上面的程序,然后点击几下界面后,界面就‘死掉’了(大家可以Resize看一下,或者点击一下窗口的Close按钮),‘死掉’有可能是死锁造成的,只是可能,但是程序也没有报Exception,这就是不确定性,如果Swing的stub不在EDT里面运行,带给程序很多的不确定性。在我以前看到的项目中,由于EDT的原因,引发可各种不可预测的Exception。

如果我们将上面的程序稍微改一下,将notInEDT的方法改成下面的样子:

private void notInEDT() {
	for (int i = 0; i < 4; ++i) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				while (true) {
					SwingUtilities.invokeLater(new Runnable() {
						@Override
						public void run() {
						     m_txt.setText("我在EDT中操作!");
						}
					});
					
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}).start();
	}
}

      通过修改是不是发现没前面的问题了。但是有一些新学的朋友会问,如果本来就在EDT中就不用再加入到EDT, 但是如何才知道当前的线程是否是EDT呢,请看SwingUtilities.isEventDispatchThread();想得多周到的开发Swing的人员!SwingUtilities、SwingUtilities2、SwingUtilities3这几个类在以后都会经常用到,非常方便。看了上面的例子,大家有什么感想呢?

       下面我们接着来写一个例子,我们试想一下,如果在EDT中执行一些时间长的任务会怎样呢?

 

import java.awt.BorderLayout;

/**
 * <code>NotInEDTSample</code> just demonstrates the usage of Swing EDT simply.
 * 
 * @author Jimmy.haung(SZ Team)
 * @since <i>DUI (Mar 25, 2013)</i>
 */
public class LongTaskSample extends JFrame {
	private static final long serialVersionUID = 1L;
	private JButton m_btn;

	public LongTaskSample() {
		initGUI();
		initEventHandler();
	}

	/**
	 * Init the GUI
	 */
	public void initGUI() {
		this.setTitle("a simple EDT Sample");
		m_btn = new JButton("click me to process long task");
		getContentPane().add(m_btn, BorderLayout.CENTER);
	}
	/**
	 * Bind the event to the component.
	 */
	public void initEventHandler(){
		m_btn.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				longTask();
			}
		});
	}

	/**
	 * Use about five seconds to process this task.
	 */
	private void longTask() {
		//为true,请看 #main(String[])
		System.err.println(SwingUtilities.isEventDispatchThread());
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				try {
					LongTaskSample oFrame = new LongTaskSample();
					oFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
					oFrame.setLocationRelativeTo(null);
					oFrame.setSize(300, 200);
					oFrame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

}

        

       点击了按钮后,我们发现程序死掉了大约5秒后,就醒来了,这就是“装死”的现象。所以我们看到在EDT里面运行时间长的任务的结果会引发什么后果,就会觉得很慢。上面的两个例子只是说明了一丁点的问题。在大家以后的项目中将会遇到更多问题。那么现在的问题是如果来改善上面的问题,我们应该在其他的线程中执行时间长的任务,而在EDT只是负责界面的显示,以及界面数据的修改、获取等,这以后还会讲,在这里提示一下,SwingWorker可以很好解决上面的问题。马马虎虎终于完成了第一篇文章。如果新学的朋友,还是不懂得话,请看http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html。如果还是不明白,不要紧,以后会慢慢体会到的。前面的几篇的文章将会将一些Swing基本的东西,讲完基础的东西后将会开始我们的Fast-DUI之旅。预告一下,下一章将会是布局(Layout),如何简单使用布局管理器来实现复杂的布局。

   这里先预告一下我们以后要构建Fast-DUI的LAF(这只是其中的一种Skin,大家可以根据自己的情况来改变Skin),如下图:



 

  • 大小: 38.1 KB
分享到:
评论

相关推荐

    javaSwing皮肤大全.rar

    标题“javaSwing皮肤大全.rar”表明这是一个包含多种Swing LookAndFeel皮肤的压缩文件集合。这个压缩包特别之处在于它包含了50种不同的Look and Feel jar包,这些jar包可以被引入到Java项目中,为Swing应用程序增添...

    Java Swing 24种皮肤合集以及使用方法

    Java Swing 是Java GUI(图形用户界面)开发的一个重要库,它是AWT(Abstract Window Toolkit)的扩展,提供了更丰富的组件和更好的本地化支持。Swing提供了丰富的组件集合,包括按钮、文本框、面板等,使得开发者...

    Java Swing大神必经之路

    第3篇 Java Swing大神必经之路3:JavaSwing-AbstractButton详解 本篇文章对 AbstractButton 进行了详细的介绍,包括其定义、构造方法、setParameter() 等,幫助讀者更好地理解 AbstractButton 的使用。 第4篇 Java ...

    90个java-swing基础例子.zip

    10. **线程管理**:Swing不是线程安全的,所有对Swing组件的修改应在Event Dispatch Thread (EDT)中进行,以避免并发问题。 通过这90个基础例子,你可以逐步了解和掌握如何使用Swing创建组件,布局组件,处理用户...

    java+swing聊天室

    Java Swing聊天室是一种基于Java GUI(图形用户界面)框架Swing构建的实时通信应用程序。Swing是Java标准库的一部分,提供了丰富的组件库,用于创建桌面应用程序。在这个项目中,我们将探讨如何利用Java Swing来实现...

    Java Swing桌面开发经典案例

    Java Swing是Java平台上用于构建桌面应用程序的一个重要工具包,它属于Java Foundation Classes (JFC)的一部分。Swing提供了丰富的组件库,使得开发者可以创建出功能强大、用户界面友好的图形用户界面(GUI)。本...

    JavaSwing小程序

    在本JavaSwing小程序中,我们可能涉及到Swing的基本用法、组件使用、布局管理以及事件处理等多个知识点。 1. **Swing组件**:Swing 提供了许多组件,如 JButton、JLabel、JTextField、JTextArea、JCheckBox、...

    java swing简单开发实例

    Java Swing是Java GUI(图形用户界面)库的一部分,主要用于创建桌面应用程序。它是Java AWT(Abstract Window Toolkit)的扩展,提供了更多的组件、事件处理机制以及更丰富的用户界面。在这个"java swing简单开发...

    Java Swing 2nd Edition

    《Java Swing 2nd Edition》是由Manning出版社于2005年出版的一本权威性的技术书籍,专注于Java Swing框架的深入学习与实践。Swing是Java AWT(Abstract Window Toolkit)库的一部分,用于构建图形用户界面(GUI)。...

    Java Swing图形界面开发与案例详解及随书实例代码

    Java Swing是Java编程语言中用于构建桌面应用程序图形用户界面(GUI)的一个库,它是Java Foundation Classes (JFC)的一部分。Swing提供了丰富的组件集,包括按钮、文本框、菜单等,使得开发者能够创建功能强大的、...

    Java Swing 图形界面开发--文章的源码

    Java Swing 是Java平台上的一个图形用户界面(GUI)工具包,它是Java Foundation Classes (JFC) 的一部分。Swing 提供了丰富的组件和布局管理器,使得开发者可以创建功能强大的桌面应用程序。在这个“Java Swing ...

    JavaSwing帮助文档

    这个“JavaSwing帮助文档”是专为学习和深入理解Swing而设计的一份详细教程,无论你是Java GUI编程的新手还是有一定经验的开发者,都能从中受益。 Swing 提供了一组组件,这些组件可以构建出功能丰富的、美观的窗口...

    Java Swing图形界面开发与案例详解

    Java Swing是Java语言中用于构建桌面应用程序用户界面的库,它是Java Foundation Classes (JFC)的一部分。Swing提供了丰富的组件集,允许开发者创建美观且功能强大的图形用户界面(GUI)。在《Java Swing图形界面...

    java swing界面开发的一个抓取快递接口工具

    Java Swing是Java标准库中的一个组件,用于构建桌面应用程序的用户界面。在本项目中,"java swing界面开发的一个抓取快递接口工具"是一个利用Java Swing来设计图形用户界面(GUI)的应用,其主要功能是与快递100查询...

    java Swing开发的资源管理器带源码

    Swing 是在早期的AWT(Abstract Window Toolkit)之上建立的,提供了更多的功能和更好的可定制性。本资源管理器就是使用Java Swing进行开发的,这意味着它利用了Swing的各种组件和设计模式来实现文件和目录的浏览、...

    java swing ppt

    Swing还提供了事件分发线程(Event Dispatch Thread,EDT),确保所有的Swing组件操作都在同一线程中执行,从而避免了UI线程安全问题。 ### 布局管理器 Swing继承并扩展了AWT的布局管理器概念,提供了更多的布局...

    基于java swing的指针时钟

    Java Swing 是Java GUI(图形用户界面)库的一部分,它提供了丰富的组件和工具,用于构建桌面应用程序。在这个项目中,我们关注的是如何使用Swing来创建一个指针时钟。对于Java初学者来说,这是一个很好的练习,因为...

    java swing

    Java Swing 是Java平台上用于构建图形用户界面(GUI)的一个库,它是Java Foundation Classes (JFC)的一部分。在Java Swing中,你可以创建丰富的、交互式的窗口应用程序,包括按钮、文本框、菜单、滚动面板等组件。...

    图书管理系统(JavaSwing)

    《图书管理系统(JavaSwing)》是一个基于Java Swing技术实现的简单桌面应用程序,旨在帮助用户管理和组织图书信息。Java Swing是Java Foundation Classes (JFC)的一部分,提供了丰富的图形用户界面(GUI)组件,用于...

    javaSwing教程

    这个“javaSwing教程”包含了深入学习Swing组件的基础知识,这对于任何想要构建美观、功能丰富的桌面应用程序的Java开发者来说是必不可少的。 Swing 提供了一套丰富的组件库,用于创建窗口应用,包括按钮、文本框、...

Global site tag (gtag.js) - Google Analytics