java GUI冻结选择JCombobox时,如何在Swing应用程序中使用计时器,并在actionListener中使用条件语句?
我正在一个登录框架上工作,在这个框架中,我用用户创建的数据库检索和填充JComboBox,然后根据从JComboBox中选择的项设置JLabel的文本。 我想延迟执行并显示“连接…”当用户从JComboBox中选择一个项目时,JLabel中的文本,但当我选择一个项目时,GUI冻结,5秒后显示“已连接”,跳过“正在连接…”杰拉贝尔
事先非常感谢
package com.softoak.dba;
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import javax.swing.JComboBox;
public class Login{
private JFrame frame;
static ArrayList<String> dbcom = new ArrayList<String>();
static String[] usecom;
JLabel status = new JLabel("•");
JLabel lblNotConnected;
/**
* Launch the application.
*/
public static void main(String[] args) throws Exception{
Connection m_Connection = DriverManager.getConnection("jdbc:sqlserver://localhost;integratedSecurity=true");
String dbs = "SELECT * FROM sys.databases WHERE owner_sid != 1";
Statement st = m_Connection.createStatement();
ResultSet m_ResultSet = st.executeQuery(dbs);
dbcom.add("-None-");
while(m_ResultSet.next()){
dbcom.add(m_ResultSet.getString(1));
}
usecom = new String[dbcom.size()];
usecom = dbcom.toArray(usecom);
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Login window = new Login();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Login() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
status.setBounds(385, 235, 10, 10);
status.setForeground(Color.red);
frame.getContentPane().add(status);
JLabel lblLoginApplication = new JLabel("Login Application");
lblLoginApplication.setFont(new Font("Lucida Calligraphy", Font.BOLD, 20));
lblLoginApplication.setBounds(120, 25, 220, 30);
frame.getContentPane().add(lblLoginApplication);
JComboBox comboBox = new JComboBox(usecom);
comboBox.setBounds(230, 80, 110, 30);
comboBox.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
if (comboBox.getSelectedIndex() == 1 || comboBox.getSelectedIndex() == 2) {
lblNotConnected.setText("Connecting...");
try{
Thread.sleep(5000);
}catch(InterruptedException ex){
JOptionPane.showMessageDialog(null,ex.getMessage());
}
status.setForeground(Color.green);
lblNotConnected.setText("Connected");
JOptionPane.showMessageDialog(null, "Connected");
}
else{
status.setForeground(Color.red);
lblNotConnected.setText("Not Connected");
}
}
});
frame.getContentPane().add(comboBox);
JLabel lblSelectDatabase = new JLabel("Select Database");
lblSelectDatabase.setFont(new Font("Microsoft Sans Serif", Font.BOLD, 14));
lblSelectDatabase.setBounds(91, 79, 129, 30);
frame.getContentPane().add(lblSelectDatabase);
lblNotConnected = new JLabel("Not Connected");
lblNotConnected.setFont(new Font("Elephant", Font.PLAIN, 12));
lblNotConnected.setBounds(280, 230, 110, 20);
frame.getContentPane().add(lblNotConnected);
}
}
# 1 楼答案
在侦听器中执行的代码在
Event Dispatch Thread(EDT)
上执行。当您使用Thread.sleep()
时,这会导致EDT休眠,这意味着GUI无法重新绘制自身。阅读Swing教程中关于Concurrency的部分以了解更多信息出于上述原因,任何可能长时间运行的任务都不应在EDT上执行。相反,你应该使用一个单独的线程。查看上述教程中的
SwingWorker
。你可以用线。sleep()并发布值以按需显示但是,为什么您希望用户等待5秒钟?我知道我会感到沮丧
也许你应该使用
ProgressMonitor
让用户知道你可能正在执行一个长时间运行的任务。阅读Swing教程中关于How to Use Progress Bars的部分,了解更多信息和工作示例