当JCombobox被选中时,GUI冻结,如何在Swing应用程序中使用定时器和actionListener中的条件语句



我正在一个登录框架上工作,在那里我正在检索和填充用户创建的数据库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教程中关于如何使用进度条的部分,了解更多信息和工作示例。

相关内容

最新更新