有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

    在侦听器中执行的代码在Event Dispatch Thread(EDT)上执行。当您使用Thread.sleep()时,这会导致EDT休眠,这意味着GUI无法重新绘制自身。阅读Swing教程中关于Concurrency的部分以了解更多信息

    出于上述原因,任何可能长时间运行的任务都不应在EDT上执行。相反,你应该使用一个单独的线程。查看上述教程中的SwingWorker。你可以用线。sleep()并发布值以按需显示

    但是,为什么您希望用户等待5秒钟?我知道我会感到沮丧

    也许你应该使用ProgressMonitor让用户知道你可能正在执行一个长时间运行的任务。阅读Swing教程中关于How to Use Progress Bars的部分,了解更多信息和工作示例