`
fen9ye
  • 浏览: 6570 次
  • 性别: Icon_minigender_1
  • 来自: 广东
最近访客 更多访客>>
社区版块
存档分类
最新评论

Swing与线程

阅读更多
    无论何时运行一个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多线程下载器是一种利用Java Swing库构建的图形用户界面(GUI)应用程序,它具备多线程下载功能,并支持断点续传。这样的工具类似于我们熟知的迅雷下载管理器,允许用户同时下载多个文件,提高下载速度,...

    JAVASWING多线程产生随机球

    在“JAVASWING多线程产生随机球”的项目中,开发者利用Swing创建了一个互动的应用程序,用户可以通过鼠标点击在界面上生成一个球体,这个球体会以随机的方向和速度在窗口内移动。下面将详细解释这个项目涉及的知识点...

    基于swing的多线程聊天室

    【基于Swing的多线程聊天室】是一个Java应用程序,它利用了Swing库来构建图形用户界面(GUI)并采用多线程技术实现多用户之间的实时通信。Swing是Java Standard Edition(Java SE)的一部分,提供了丰富的组件库用于...

    Swing线程的深入理解和SwingWorker基础知识介绍

    Swing线程的深入理解和SwingWorker基础知识介绍 Swing线程是Java程序设计中的一种重要概念,用于处理图形用户界面(GUI)中的线程问题。在本文中,我们将深入探讨Swing线程的理解和SwingWorker基础知识,并通过实例...

    Java雷电游戏,主要用SWING和Java的进程,纯Java代码写的,主要为开发人员对Java线程的认识

    开发者可以通过研究游戏源码了解如何创建和启动线程,以及如何使用synchronized关键字和wait/notify机制实现线程间的通信与同步,以确保游戏运行的稳定性和响应速度。 此外,Java的事件驱动模型在处理用户交互时也...

    JAVA 开发 Swing与多线程

    在Java开发中,Swing库是用来构建图形用户界面(GUI)的工具包,而多线程则是提升程序并发性能和响应能力的关键技术。Swing虽然是Java语言的一部分,但它设计为单线程模型,主要是为了简化GUI编程并避免复杂的同步...

    几个swing多线程的例子

    Java Swing 是一个用于构建桌面应用程序的用户界面工具包,它是Java Foundation Classes (JFC) 的一部分...对于初学者来说,通过研究提供的 "几个swing多线程的例子",可以更好地理解如何在实践中结合 Swing 和多线程。

    Java开发中的线程安全选择与Swing

    ### Java开发中的线程安全选择与Swing 在Java开发中,Swing作为构建桌面应用程序图形用户界面(GUI)的主要工具之一,其设计目标是为了提供一个强大、灵活且易于使用的框架。Swing允许开发者轻松创建自定义组件或...

    基于swing多线程的赛马游戏

    本项目“基于Swing多线程的赛马游戏”是一个很好的实践案例,它结合了Swing图形用户界面(GUI)和多线程技术,以模拟赛马比赛并允许用户下注和预测结果。 首先,我们要理解Swing的基础。Swing是Java的一个图形用户...

    Swing线程的最后讨论 -- 利用异步模型

    【Swing线程的最后讨论 -- 利用异步模型】 Swing框架遵循单线程规则,即所有UI组件在同一时间只能被一个线程访问,通常这个线程就是事件派发线程。这一规则是为了避免多线程环境下的竞态条件和同步问题,确保组件的...

    swing,线程和网络编程教学示例

    在Java编程领域,Swing、线程和网络编程是三个重要的子领域,它们共同构建了丰富的应用程序基础。Swing主要用于创建图形用户界面(GUI),线程则是多任务处理的核心,而网络编程则允许程序通过互联网进行通信。让...

    Javaswing多线程.zip

    在Swing中,我们通常使用`javax.swing.Timer`类来实现这种定时任务,因为它与Swing事件调度线程(Event Dispatch Thread, EDT)协同工作,确保了UI更新的线程安全。 以下是一些关于Java Swing和多线程的关键知识点...

    Swing 线程之SwingUtilities invokeLater docx

    Swing 线程之 SwingUtilities invokeLater Swing 线程模型是 Java 中一个非常重要的概念,它是 Java 的图形用户界面(GUI)程序设计中的一部分。Swing 是基于 MVC 模式(Model-View-Controller)设计的,它提供了一...

    Swing线程基础经典

    Swing线程基础是Java GUI编程中的重要概念,特别是对于使用Swing库构建桌面应用程序的开发者而言。Swing设计遵循单线程模型,确保UI组件的线程安全性和响应性。以下是Swing线程基础的详细说明: 1. **Swing应用程序...

    swing界面socket多线程聊天室

    在本项目中,“swing界面socket多线程聊天室”是一个基于Java Swing的客户端-服务器通信应用,它利用TCP协议来实现实时的聊天功能。这个系统不仅提供了群聊和私聊的功能,还允许用户发送文件,并且具备用户登录与...

    基于java swing的多线程电梯调度模拟

    线程内部可能包含电梯的状态管理(如上行、下行、停止)、目的地处理以及与其它线程的同步机制(如wait()和notify()方法)。 接着是"ListFrame.java"。这个名字暗示着它可能是一个Swing的JFrame子类,用于构建用户...

    Java Swing多线程死锁问题解析

    代码执行前判断是否处于Swing线程当中(使用SwingUtilities.isEventDispatchThread()方法),如果不是,则需要通过SwingUtilities.invokeLater(Runnable)执行,否则则直接执行代码。 在Java Swing多线程死锁问题...

    Java Swing 线程 下雪效果

    在Java Swing中创建动态、交互式的应用,线程管理是一个关键的概念。当我们谈论"下雪效果"时,这意味着在Swing程序中实现一个模拟下雪场景的动画。 首先,要实现下雪效果,我们需要理解Swing的事件处理机制。Swing...

    swing 显示时间

    在本例中,我们将探讨如何利用Swing来显示当前时间,并结合多线程的概念确保时间的实时更新。 首先,`Show.java`文件很可能包含了一个Java类,该类创建了一个Swing窗口并在其中显示时间。Swing中的`JFrame`是窗口的...

    Swing线程基础.pdf

    Swing线程基础详解 Swing作为Java的图形用户界面库,它的线程管理机制是理解和正确使用Swing的关键。Swing程序中的线程主要包括三种类型:初始化线程、UI事件调度线程(Event Dispatch Thread,简称EDT)以及任务...

Global site tag (gtag.js) - Google Analytics