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),如下图:
相关推荐
标题“javaSwing皮肤大全.rar”表明这是一个包含多种Swing LookAndFeel皮肤的压缩文件集合。这个压缩包特别之处在于它包含了50种不同的Look and Feel jar包,这些jar包可以被引入到Java项目中,为Swing应用程序增添...
Java Swing 是Java GUI(图形用户界面)开发的一个重要库,它是AWT(Abstract Window Toolkit)的扩展,提供了更丰富的组件和更好的本地化支持。Swing提供了丰富的组件集合,包括按钮、文本框、面板等,使得开发者...
第3篇 Java Swing大神必经之路3:JavaSwing-AbstractButton详解 本篇文章对 AbstractButton 进行了详细的介绍,包括其定义、构造方法、setParameter() 等,幫助讀者更好地理解 AbstractButton 的使用。 第4篇 Java ...
10. **线程管理**:Swing不是线程安全的,所有对Swing组件的修改应在Event Dispatch Thread (EDT)中进行,以避免并发问题。 通过这90个基础例子,你可以逐步了解和掌握如何使用Swing创建组件,布局组件,处理用户...
Java Swing聊天室是一种基于Java GUI(图形用户界面)框架Swing构建的实时通信应用程序。Swing是Java标准库的一部分,提供了丰富的组件库,用于创建桌面应用程序。在这个项目中,我们将探讨如何利用Java Swing来实现...
Java Swing是Java平台上用于构建桌面应用程序的一个重要工具包,它属于Java Foundation Classes (JFC)的一部分。Swing提供了丰富的组件库,使得开发者可以创建出功能强大、用户界面友好的图形用户界面(GUI)。本...
在本JavaSwing小程序中,我们可能涉及到Swing的基本用法、组件使用、布局管理以及事件处理等多个知识点。 1. **Swing组件**:Swing 提供了许多组件,如 JButton、JLabel、JTextField、JTextArea、JCheckBox、...
Java Swing是Java GUI(图形用户界面)库的一部分,主要用于创建桌面应用程序。它是Java AWT(Abstract Window Toolkit)的扩展,提供了更多的组件、事件处理机制以及更丰富的用户界面。在这个"java swing简单开发...
《Java Swing 2nd Edition》是由Manning出版社于2005年出版的一本权威性的技术书籍,专注于Java Swing框架的深入学习与实践。Swing是Java AWT(Abstract Window Toolkit)库的一部分,用于构建图形用户界面(GUI)。...
Java Swing是Java编程语言中用于构建桌面应用程序图形用户界面(GUI)的一个库,它是Java Foundation Classes (JFC)的一部分。Swing提供了丰富的组件集,包括按钮、文本框、菜单等,使得开发者能够创建功能强大的、...
Java Swing 是Java平台上的一个图形用户界面(GUI)工具包,它是Java Foundation Classes (JFC) 的一部分。Swing 提供了丰富的组件和布局管理器,使得开发者可以创建功能强大的桌面应用程序。在这个“Java Swing ...
这个“JavaSwing帮助文档”是专为学习和深入理解Swing而设计的一份详细教程,无论你是Java GUI编程的新手还是有一定经验的开发者,都能从中受益。 Swing 提供了一组组件,这些组件可以构建出功能丰富的、美观的窗口...
Java Swing是Java语言中用于构建桌面应用程序用户界面的库,它是Java Foundation Classes (JFC)的一部分。Swing提供了丰富的组件集,允许开发者创建美观且功能强大的图形用户界面(GUI)。在《Java Swing图形界面...
Java Swing是Java标准库中的一个组件,用于构建桌面应用程序的用户界面。在本项目中,"java swing界面开发的一个抓取快递接口工具"是一个利用Java Swing来设计图形用户界面(GUI)的应用,其主要功能是与快递100查询...
Swing 是在早期的AWT(Abstract Window Toolkit)之上建立的,提供了更多的功能和更好的可定制性。本资源管理器就是使用Java Swing进行开发的,这意味着它利用了Swing的各种组件和设计模式来实现文件和目录的浏览、...
Swing还提供了事件分发线程(Event Dispatch Thread,EDT),确保所有的Swing组件操作都在同一线程中执行,从而避免了UI线程安全问题。 ### 布局管理器 Swing继承并扩展了AWT的布局管理器概念,提供了更多的布局...
Java Swing 是Java GUI(图形用户界面)库的一部分,它提供了丰富的组件和工具,用于构建桌面应用程序。在这个项目中,我们关注的是如何使用Swing来创建一个指针时钟。对于Java初学者来说,这是一个很好的练习,因为...
Java Swing 是Java平台上用于构建图形用户界面(GUI)的一个库,它是Java Foundation Classes (JFC)的一部分。在Java Swing中,你可以创建丰富的、交互式的窗口应用程序,包括按钮、文本框、菜单、滚动面板等组件。...
《图书管理系统(JavaSwing)》是一个基于Java Swing技术实现的简单桌面应用程序,旨在帮助用户管理和组织图书信息。Java Swing是Java Foundation Classes (JFC)的一部分,提供了丰富的图形用户界面(GUI)组件,用于...
这个“javaSwing教程”包含了深入学习Swing组件的基础知识,这对于任何想要构建美观、功能丰富的桌面应用程序的Java开发者来说是必不可少的。 Swing 提供了一套丰富的组件库,用于创建窗口应用,包括按钮、文本框、...