`
云上太阳
  • 浏览: 128620 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Swing多线程编程

阅读更多

    基本上所有GUI库都是单线程的,Swing就是一种GUI库。什么意思呢?就是说所有对UI的更新都是在主线程中进行,这也是Swing的EDT线程(事件派发线程)也被叫UI线程的原因。如果在UI线程中执行比较耗时的操作,界面会卡住。Swing有个单线程规范,只要牢记会避免很多大坑:所有界面操作的更新都应该在EDT线程执行,所有耗时的操作都应该在单独线程中执行。

     请牢记上面的红字部分,然后我们开始一个实例:点击按钮后,按钮显示秒数,每过一秒显示加1。下面是第一个版本

package com.albert.frame;

import java.awt.BorderLayout;

public class TestSwing extends JFrame {
	private JPanel contentPane;

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					TestSwing frame = new TestSwing();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	public TestSwing() {
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
		
		final JButton button = new JButton("点击");
		contentPane.add(button, BorderLayout.CENTER);
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
an				for(int i=0;i<=5;i++){
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}
					button.setText(i+"");
				}
			}
		});
	}

}

 运行代码点击按钮后,会发现界面卡住了,然后过了5秒后,按钮上直接显示了5。而不是我们期望的从0开始每隔一秒加1。

 

      这是上面原因呢?很明显这个违背了上面的原则:不能在EDT线程中进行耗时操作。因为你的耗时操作占用了EDT线程,然后界面更新会去耗时操作后面排队,最后同一个组件的界面更新会合并成最后一个也就是直接显示5。需要说明的是Swing组件的各种事件监听方法都是在EDT线程调用的,比如单击事件。

 

      既然程序并没有按照我们的想法执行,是因为违背了GUI单线程的原则,那我们再次修改下程序,把耗时操作的代码加入到单独的线程中,只贴出修改的部分

button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				new Thread(new Runnable() {
					public void run() {
						for(int i=0;i<=5;i++){
							try {
								Thread.sleep(1000);
							} catch (InterruptedException e1) {
								e1.printStackTrace();
							}
							button.setText(i+"");
						}
					}
				}).start();
			}
		});
}

 

 

运行程序并且点击按钮,发现程序按照我们的期望执行了。是不是很开心啊,可是不要高兴的太早,虽然功能实现了,但是还是违背了GUI单线程原则:在EDT线程中进行界面的更新。而我们在单独线程中运行了这段界面更新操作的代码:button.setText(i+"")。

       简直头大,button.setText()和我们的耗时操作是一个代码块怎么能分开在两个线程执行啊?日了狗日了!!其实Swing给我们提供了一个工具类SwingUtilities,里面有个方法invokeLater(Runnable runnable),这个方法的作用就是把一个runnable(就是一个任务,很多初学者学习线程认为Runnable也是线程的一部分,其实Runnable只是一个有一个run方法声明的接口)传到EDT线程中,让EDT线程去执行。再次修改代码

button.addActionListener(new ActionListener() {
			int i;
			public void actionPerformed(ActionEvent e) {
				new Thread(new Runnable() {
					public void run() {
						for(i=0;i<5;i++){
							try {
								Thread.sleep(1000);
							} catch (InterruptedException e1) {
								e1.printStackTrace();
							}
							SwingUtilities.invokeLater(new Runnable() {
								public void run() {
									button.setText(i+"");
								}
							});
						}
					}
				}).start();
			}
		});
	}

 程序执行的结果也就是我们期望的,并且也符合了GUI单线程的原则,皆大欢喜了。

 然后介绍下Swing提供给我们类SwingWorker,在doInbackground()中执行耗时操作,然后返回结果,可以在done()方法中用get()获取到doInbackground()返回的结果进行界面刷新。

SwingWorker worker = new SwingWorker<Integer, Void>() {
				@Override
				protected Integer doInBackground() throws Exception {
					//耗时操作。。。
					
					return 0;
				}
				@Override
				protected void done() {
					super.done();
					//上面的耗时操作完成后把done()交给EDT执行。
				}
			};

 

好了,以上就是Swing的线程说明,希望有帮助

 

0
0
分享到:
评论

相关推荐

    JAVA编写的多线程小弹球测试

    JAVA写得小弹球,多线程。随机出现,随机选择颜色,遇到墙壁反弹。

    JAVA Swing图形用户界面编程 多线程编程 弹球游戏

    用户能通过GUI组件指定生成小球的数量,每个小球将从随机的位置出现,并具有随机颜色,随机速度以及随机的运动方向,小球沿初始方向匀速运动,当碰到窗口边缘时,小球将依据受力原理改变运动方向(可简化考虑,受力...

    java 多线程编程

    java多线程最好的学习资料,永久收藏!

    java多线程文件传输(基于swing)

    基于socket的多线程文件传输,包中含有整个工程的源代码(有详细的注解) 和 直接运行的打包生成的jar文件 。其中swing界面有待优化.....

    Java的多线程-线程间的通信.doc

    Java的多线程-线程间的通信.doc

    图解java多线程设计模式

    264张图表 + 300段Java示例程序 = 轻松学习多线程编程 日本经典多线程入门书,原版长销11年! 1.图文并茂 通俗易懂 日本资-深技术作家、《程序员的数学》作者结城浩执笔,264张图表(UML类图、时序图、Timethreads...

    一个通用的Java线程池类

    因为涉及到Socket编程,所以一定会使用多线程编程。这里本人翻写一个通用的线程池类,它可以用来作为工具类处理许多多线程问题。代码注释非常详尽,一行注释一行代码。 阅读对象:非常熟悉Java的基本概念,并且熟悉...

    线程 JAVA java线程 java线程第3版 java线程第2版第3版合集

    用线程编程是技巧性很强的且不可移植。 而在Java中却完全不同。Java的线程工具易于使用,并且像Java中的其他东西一样可以在不同的平台之间移植。这是一件好事,因为如果没有线程,那么除了最简单的applet之外,几乎...

    一个可以直接使用的通用线程池Util

    使用步骤: 1.下载解压之后,在控制台运行javac...因为涉及到Socket编程,所以一定会使用多线程编程。这里本人翻写一个通用的线程池类,它可以用来作为工具类处理许多多线程问题。代码注释非常详尽,一行注释一行代码。

    java swing闹钟

    自己以前大二的时候闲暇时候写的,现在对以前的代码进行了整合,修复了部分bug以及资源占用过高,主要是因为当时对java多线程编程不是很熟悉。很实用的一个跨平台的闹钟程序,同时提供了较多的个性化定制属性,比如...

    推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 16.多线程(共44页).ppt

    多线程(共44页).ppt 推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 17.网络编程(共42页).ppt 推荐优质Java课程 疯狂Java语言编程 Java入门到进阶教程 18.类加载与反射(共25页).ppt

    swing界面设计之JTree

    是一本pdf格式的书,这本书主要介绍了SWing高级中的JTree编程的所有功能。

    新手学java7编程

    本书正是为了帮助你学习Java程序设计基础而编写的。本书采用循序渐进的教学方法,...还介绍了Java的一些最重要的高级功能,如多线程编程和泛型。本书最后介绍了Swing。学完本书后,读者将会牢固地掌握Java编程精髓。

    java swing坦克大战程序idea编程环境

    1.swing控件的综合运用 2.多线程的运用 3.对象池技术的使用 4.设计模式的使用 5.文件流的读写操作

    java(awt/swing)局域网即时聊天源码

    运用面向对象编程,继承、封装和多态等,Java语言的基本语法,Java IO;多线程编程,网络编程,序列化,反射,程序国际化;基本的界面编程(AWT和Swing)等基础知识。是学习java基础的一个极好案例。

    Java案例精粹150例代码

    本书通过150个实例全面介绍了Java编程基础、多线程编程、输入/输出编程、Applet编程、Swing图形界面编程、多媒体和图形图像处理编程、网络编程、数据库编程、B/S结构编程、Web Service编程、EJB编程、安全性编程、...

    socket编程,C/S结构,Swing编写的小代码---考试系统

    请先运行ServerMainClass服务端,再启动客户端LoginFrame,用户名密码在user.dat文件里用文本文件打开修改

    java+JDK+examples.rar_Swing Examples_java Applet_java file handl

    共有19个章节,169个实例,内容涉及Java的语言基础、面向对象程序设计、数字处理、数组与集合、字符串、异常处理、文件操作、多线程、Swing编程、图形和多媒体编程、反射机制、网络程序设计、数据库编程、Applet、...

    java swing闹钟程序

    自己以前大二的时候闲暇时候写的,现在对以前的代码进行了整合,修复了部分bug以及资源占用过高,主要是因为当时对java多线程编程不是很熟悉。很实用的一个跨平台的闹钟程序,同时提供了较多的个性化定制属性,比如...

Global site tag (gtag.js) - Google Analytics