Swing多线程编程
来源:互联网 发布:淘宝客服ipad 编辑:程序博客网 时间:2024/05/22 15:50
- 博客分类:
基本上所有GUI库都是单线程的,Swing就是一种GUI库。什么意思呢?就是说所有对UI的更新都是在主线程中进行,这也是Swing的EDT线程(事件派发线程)也被叫UI线程的原因。如果在UI线程中执行比较耗时的操作,界面会卡住。Swing有个单线程规范,只要牢记会避免很多大坑:所有界面操作的更新都应该在EDT线程执行,所有耗时的操作都应该在单独线程中执行。
请牢记上面的红字部分,然后我们开始一个实例:点击按钮后,按钮显示秒数,每过一秒显示加1。下面是第一个版本
伦理片 http://www.dotdy.com/
- 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();
- }
- });
- }
影音先锋电影 http://www.iskdy.com/
运行程序并且点击按钮,发现程序按照我们的期望执行了。是不是很开心啊,可是不要高兴的太早,虽然功能实现了,但是还是违背了GUI单线程原则:在EDT线程中进行界面的更新。而我们在单独线程中运行了这段界面更新操作的代码:button.setText(i+"")。
简直头大,button.setText()和我们的耗时操作是一个代码块怎么能分开在两个线程执行啊?日了狗日了!!其实Swing给我们提供了一个工具类SwingUtilities,里面有个方法invokeLater(Runnable runnable),这个方法的作用就是把一个runnable(就是一个任务,很多初学者学习线程认为Runnable也是线程的一部分,其实Runnable只是一个有一个run方法声明的接口)传到EDT线程中,让EDT线程去执行再次修改。
- Swing多线程编程
- Swing多线程编程
- Swing多线程编程
- Swing多线程编程
- Swing多线程编程
- Swing多线程
- swing多线程
- Swing编程
- Swing中的多线程
- Swing与多线程-小结
- Swing中的多线程
- swing中多线程
- 关于swing多线程理解
- Java Swing 编程一二
- 第十二章:Swing编程
- Java Swing编程
- Swing编程JTable表格
- 一Swing编程起步
- uva 10118 ——Free Candies
- Yii2使用Markdown编辑器
- C#——编程风格
- spring框架学习(四)自动装配
- 算法之5--回溯法解决八皇后问题
- Swing多线程编程
- readlines()与len()、read()与count()判断文本的行数
- Android中Acition和Category常量表
- JavaScript的“孙悟空”之72变
- PullToRefreshLibrary设置label提示信息注意点
- 【C语言提高29】两个辅助指针变量挖字符串
- 素数求和问题
- epoll pattern research
- 20151206 重新搭建oracle11g单机环境 oracle篇