无论何时运行一个Swing应用程序,都会自动创建三个线程。第一个是主线程,它运行程序的主方法。第二个线程称为工具包线程,它负责捕获系统事件,如键盘按下或鼠标移动。捕获的事件将发送到第三个线程(事件派发进程)。
所有的事件(如键盘按下、鼠标移动)都放置到一个事件队列中。Java.awt.EventQueue对象负责从这个队列中取出事件并适当地派发它们。EventQueue的派发机制由单独的一个线程管理,这个线程称为事件派发线程(EDT,Event Dispatch Thread)。
比如在JTextField按下一个键,EDT把这个按键事件派发到这个组件的键监听器。这个组件接着更新他的模式(执行actionPerformed方法),并把一个绘制请求发布到事件队列(EventQueue)。EDT从这个队列中取出这个绘制请求并再次通知这个组件,让它重新绘制自身。
运用Swing有两个要注意的地方:
一是Swing不是线程安全的,只能在事件派发线程上访问Swing组件。多线程操控组件可能导致死锁。以前把Swing写在主线程方法是不正确的,应该借用SwingUtilities的invokeLater或invokeAndWait方法,其他线程通过这两个方法可以将代码放到事件队列中。其中invokeLater()方法是异步的,即一旦事件被发往事件队列,invokeLater的调用会立即返回。而invokeAndWait()阻塞当前进程并等待,直到EDT执行该事件。
正确的写法如下:
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
public void run() {
//.......
}
});
}
第二个要注意的地方是不要让EDT执行耗时较长的操作,例如读写文件,将阻塞整个UI。在运行这个耗时较长的操作时不能派发事件,也不能执行屏幕更新。
public class FreezeEDT extends JFrame implements ActionListener {
private JButton freezer;
public FreezeEDT() {
super("Freeze");
freezer = new JButton("Freeze");
freezer.addActionListener(this);
add(freezer);
pack();
}
public void actionPerformed(ActionEvent e) {
try {
Thread.sleep(4000);
} catch (InterruptedException evt) {
}
}
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
FreezeEDT edt = new FreezeEDT();
edt.setVisible(true);
}
});
}
}
这里让EDT线程休眠了四秒,按钮看起来像冻结了一样。为了避免执行耗时操作,一般是创建另外一个线程,但前面已经说过,只能在EDT线程访问Swing组件,所以在创建新线程的同时仍要将新线程里访问Swing组件的代码交给invokeLater方法。
改进代码如下:
public class FreezeEDT extends JFrame implements ActionListener {
private JButton freezer;
public FreezeEDT() {
super("Freeze");
freezer = new JButton("Freeze");
freezer.addActionListener(this);
add(freezer);
pack();
}
public void actionPerformed(ActionEvent e) {
new Thread(new Runnable(){
public void run() {
try {
Thread.sleep(4000);
} catch (InterruptedException evt) {
}
final String hot = "Hot";
SwingUtilities.invokeLater(new Runnable(){
public void run() {
freezer.setText(hot);
}
});
}
}).start();
}
public static void main(String... args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
FreezeEDT edt = new FreezeEDT();
edt.setVisible(true);
}
});
}
}
注意:
invokeLater并不会产生新线程,其Runnable对象会被包装成一个事件,并添加到事件队列中,处理事件时只会执行run方法。
参考文献:《Java动画、图形和极富客户端效果开发》,Chet Haase&Romain Guy
分享到:
相关推荐
Java Swing多线程下载器是一种利用Java Swing库构建的图形用户界面(GUI)应用程序,它具备多线程下载功能,并支持断点续传。这样的工具类似于我们熟知的迅雷下载管理器,允许用户同时下载多个文件,提高下载速度,...
在“JAVASWING多线程产生随机球”的项目中,开发者利用Swing创建了一个互动的应用程序,用户可以通过鼠标点击在界面上生成一个球体,这个球体会以随机的方向和速度在窗口内移动。下面将详细解释这个项目涉及的知识点...
【基于Swing的多线程聊天室】是一个Java应用程序,它利用了Swing库来构建图形用户界面(GUI)并采用多线程技术实现多用户之间的实时通信。Swing是Java Standard Edition(Java SE)的一部分,提供了丰富的组件库用于...
Swing线程的深入理解和SwingWorker基础知识介绍 Swing线程是Java程序设计中的一种重要概念,用于处理图形用户界面(GUI)中的线程问题。在本文中,我们将深入探讨Swing线程的理解和SwingWorker基础知识,并通过实例...
开发者可以通过研究游戏源码了解如何创建和启动线程,以及如何使用synchronized关键字和wait/notify机制实现线程间的通信与同步,以确保游戏运行的稳定性和响应速度。 此外,Java的事件驱动模型在处理用户交互时也...
在Java开发中,Swing库是用来构建图形用户界面(GUI)的工具包,而多线程则是提升程序并发性能和响应能力的关键技术。Swing虽然是Java语言的一部分,但它设计为单线程模型,主要是为了简化GUI编程并避免复杂的同步...
Java Swing 是一个用于构建桌面应用程序的用户界面工具包,它是Java Foundation Classes (JFC) 的一部分...对于初学者来说,通过研究提供的 "几个swing多线程的例子",可以更好地理解如何在实践中结合 Swing 和多线程。
### Java开发中的线程安全选择与Swing 在Java开发中,Swing作为构建桌面应用程序图形用户界面(GUI)的主要工具之一,其设计目标是为了提供一个强大、灵活且易于使用的框架。Swing允许开发者轻松创建自定义组件或...
本项目“基于Swing多线程的赛马游戏”是一个很好的实践案例,它结合了Swing图形用户界面(GUI)和多线程技术,以模拟赛马比赛并允许用户下注和预测结果。 首先,我们要理解Swing的基础。Swing是Java的一个图形用户...
【Swing线程的最后讨论 -- 利用异步模型】 Swing框架遵循单线程规则,即所有UI组件在同一时间只能被一个线程访问,通常这个线程就是事件派发线程。这一规则是为了避免多线程环境下的竞态条件和同步问题,确保组件的...
在Java编程领域,Swing、线程和网络编程是三个重要的子领域,它们共同构建了丰富的应用程序基础。Swing主要用于创建图形用户界面(GUI),线程则是多任务处理的核心,而网络编程则允许程序通过互联网进行通信。让...
在Swing中,我们通常使用`javax.swing.Timer`类来实现这种定时任务,因为它与Swing事件调度线程(Event Dispatch Thread, EDT)协同工作,确保了UI更新的线程安全。 以下是一些关于Java Swing和多线程的关键知识点...
Swing 线程之 SwingUtilities invokeLater Swing 线程模型是 Java 中一个非常重要的概念,它是 Java 的图形用户界面(GUI)程序设计中的一部分。Swing 是基于 MVC 模式(Model-View-Controller)设计的,它提供了一...
Swing线程基础是Java GUI编程中的重要概念,特别是对于使用Swing库构建桌面应用程序的开发者而言。Swing设计遵循单线程模型,确保UI组件的线程安全性和响应性。以下是Swing线程基础的详细说明: 1. **Swing应用程序...
在本项目中,“swing界面socket多线程聊天室”是一个基于Java Swing的客户端-服务器通信应用,它利用TCP协议来实现实时的聊天功能。这个系统不仅提供了群聊和私聊的功能,还允许用户发送文件,并且具备用户登录与...
线程内部可能包含电梯的状态管理(如上行、下行、停止)、目的地处理以及与其它线程的同步机制(如wait()和notify()方法)。 接着是"ListFrame.java"。这个名字暗示着它可能是一个Swing的JFrame子类,用于构建用户...
代码执行前判断是否处于Swing线程当中(使用SwingUtilities.isEventDispatchThread()方法),如果不是,则需要通过SwingUtilities.invokeLater(Runnable)执行,否则则直接执行代码。 在Java Swing多线程死锁问题...
在Java Swing中创建动态、交互式的应用,线程管理是一个关键的概念。当我们谈论"下雪效果"时,这意味着在Swing程序中实现一个模拟下雪场景的动画。 首先,要实现下雪效果,我们需要理解Swing的事件处理机制。Swing...
在本例中,我们将探讨如何利用Swing来显示当前时间,并结合多线程的概念确保时间的实时更新。 首先,`Show.java`文件很可能包含了一个Java类,该类创建了一个Swing窗口并在其中显示时间。Swing中的`JFrame`是窗口的...
Swing线程基础详解 Swing作为Java的图形用户界面库,它的线程管理机制是理解和正确使用Swing的关键。Swing程序中的线程主要包括三种类型:初始化线程、UI事件调度线程(Event Dispatch Thread,简称EDT)以及任务...