当在其Swing线程中执行费时的业务处理时,如果在Swing线程中执行耗时的业务逻辑,例如数据库查询,文件操作在Swing线程中执行,将会导致程序界面的阻塞。
为解决上述问题,我们必须将费时的业务逻辑放在其他线程中执行,这样就不会阻塞SwingUI线程,不会使界面死锁。因此,我们必须了解Swing的事件处理机制是由EventQueue事件处理线程来控制的。
EventQueue是一个与平台无关的类,它将来自底层类和受信任的应用程序类的事件列入队列。
1.下面一个未使用EventQueue的Swing线程添加选项:
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
public class SwingSingleThreadDemo extends JFrame {
private ButtonGroup buttonGroup = new ButtonGroup(); // 按钮组
private JList list; // 列表组件
private Vector listData=new Vector(); // 列表数据
/**
* Launch the application
* @param args
*/
public static void main(String args[]) {
<span style="font-family: Arial, Helvetica, sans-serif;">SwingSingleThreadDemo frame = new SwingSingleThreadDemo();</span>
}
/**
* Create the frame
*/
public SwingSingleThreadDemo() {
super();
setBounds(100, 100, 236, 204); // 设置窗体大小位置
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JScrollPane scrollPane = new JScrollPane(); // 创建高度面板
getContentPane().add(scrollPane, BorderLayout.CENTER);
list = new JList(); // 创建列表组件
scrollPane.setViewportView(list); // 滚动面板控制列表
final JPanel buttonPanel = new JPanel(); // 创建按钮面板
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
final JButton button = new JButton(); // 创建按钮
button.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
do_button_actionPerformed(e); // 调用按钮事件处理方法
}
});
button.setText("添加列表选项"); // 设置按钮名称
buttonPanel.add(button); // 添加按钮到面板
final JPanel panel = new JPanel(); // 创建单选按钮面板
panel.setLayout(new GridLayout(0, 1)); // 使用网格布局
getContentPane().add(panel, BorderLayout.EAST);
final JRadioButton radioButton_1 = new JRadioButton(); // 创建单选按钮1
buttonGroup.add(radioButton_1);
radioButton_1.setText("单选1");
radioButton_1.setSelected(true);
panel.add(radioButton_1);
final JRadioButton radioButton_2 = new JRadioButton(); // 创建单选按钮2
buttonGroup.add(radioButton_2);
radioButton_2.setText("单选2");
panel.add(radioButton_2);
final JRadioButton radioButton_3 = new JRadioButton(); // 创建单选按钮3
buttonGroup.add(radioButton_3);
radioButton_3.setText("单选3");
panel.add(radioButton_3);
final JRadioButton radioButton_4 = new JRadioButton(); // 创建单选按钮4
buttonGroup.add(radioButton_4);
radioButton_4.setText("单选4");
panel.add(radioButton_4);
setVisible(true); // 显示窗体
}
/**
* 这是<b>添加列表选项</b>按钮的事件处理方法
* @param e 事件对象
*/
protected void do_button_actionPerformed(final ActionEvent e) {
try {
for (int i = 0; i < 10; i++) {
listData.add("选项"+listData.size());
list.setListData(listData);
Thread.sleep(1000); // 阻塞UI线程1秒
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
2.使用EventQueue的方法,添加一个线程处理费时的业务逻辑:
package Chapter11;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.ScrollPane;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
public class Demo7 extends JFrame{
//在Swing线程中执行业务处理
private JList list;
private ButtonGroup buttonGroup = new ButtonGroup();
private Vector listData = new Vector();
public Demo7(){
setTitle("Swing中执行业务处理");
setBounds(100, 100, 236, 204);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final JScrollPane scrollPane = new JScrollPane();
getContentPane().add(scrollPane,BorderLayout.CENTER);
list = new JList();
scrollPane.setViewportView(list);
final JPanel buttonPanel = new JPanel();
getContentPane().add(buttonPanel,BorderLayout.SOUTH);
final JButton button = new JButton("添加列表选项");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
do_button_actionPerformed(e);
}
});
buttonPanel.add(button);
final JPanel panel = new JPanel();//创建单选按钮面板
panel.setLayout(new GridLayout(0, 1));
getContentPane().add(panel,BorderLayout.EAST);
JRadioButton radioButton_1 = new JRadioButton("单选1");
radioButton_1.setSelected(true);//默认选中
JRadioButton radioButton_2 = new JRadioButton("单选2");
JRadioButton radioButton_3 = new JRadioButton("单选3");
JRadioButton radioButton_4 = new JRadioButton("单选4");
buttonGroup.add(radioButton_1);
buttonGroup.add(radioButton_2);
buttonGroup.add(radioButton_3);
buttonGroup.add(radioButton_4);
panel.add(radioButton_1);
panel.add(radioButton_2);
panel.add(radioButton_3);
panel.add(radioButton_4);
}
protected void do_button_actionPerformed(ActionEvent e) {//一点击按钮,自动添加数据了
new Thread(){//开辟一个新的线程执行费时业务
public void run(){
for(int i=0;i<10;i++){
Runnable runnable = new Runnable() {
@Override
public void run() {
listData.add("选项"+listData.size());
list.setListData(listData);
}
};
EventQueue.invokeLater(runnable);//在时间队列中执行Runnable对象
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}.start();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
Demo7 demo = new Demo7();
demo.setVisible(true);
}
});
}
}