我正在一个登录框架上工作,在那里我正在检索和填充用户创建的数据库JComboBox,然后我在JComboBox中选择的项目的基础上设置JLabel的文本。我想延迟执行并显示"正在连接…"文本在JLabel当用户选择一个项目从JComboBox,但当我选择一个项目的GUI冻结,5秒后它显示"连接"它跳过"连接…"JLabel .
提前感谢你。
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);
}
}
在侦听器中执行的代码在Event Dispatch Thread(EDT)
上执行。当你使用Thread.sleep()
时,这会导致EDT休眠,这意味着GUI不能重新绘制自己。有关更多信息,请阅读Swing教程中的并发部分。
由于上述原因,任何可能长时间运行的任务都不应该在EDT上执行。相反,您应该使用单独的Thread。查看上面教程中的SwingWorker
。你可以在那里使用Thread.sleep()并发布你想要显示的值。
但是,为什么要让用户等待5秒呢?我知道我会很沮丧。
也许您应该使用ProgressMonitor
来让用户知道您可能正在执行一个长时间运行的任务。请阅读Swing教程中关于如何使用进度条的部分,了解更多信息和工作示例。