从SQL数据库加载时的Java进度条

时间:2017-03-25 23:43:07

标签: java swing event-dispatch-thread jprogressbar

我的目标:从数据库加载时进度条

我目前正在制定计划程序,我的一位经理会将其用于多种用途,但主要是为员工设置每周计划。当从远程位置访问 SQL数据库时,显然需要超过一秒钟加载,我想向用户提供一些反馈,以便他们知道程序仍在运行。

我真的很喜欢一个进度条,它显示表中已加载的行中已加载的行的百分比,但我不知道是否可能。我正在考虑一些不确定的JProgressBar,它只是在建立连接并且正在处理结果集时移动。谢谢!

守则

以下代码是连接到SQL数据库并处理结果集的方法:

public static String[][] getEmps(String sqlQuery) {
    String[][] employee = new String[countRows("SELECT COUNT(*) FROM employee;")][10]; //creates array for employees
    ResultSet rs = null; //declares result set
    try(Connection conn = DriverManager.getConnection(url,uname,pass)) { //connects to database
        Integer count = 0;
        try(Statement stmt = conn.createStatement()) {
            rs = stmt.executeQuery(sqlQuery);
            while (rs.next()){
                employee[count][0] = rs.getString("fname");                 //Employee's First Name
                employee[count][1] = rs.getString("lname");                 //Employee's Last Name
                employee[count][2] = String.valueOf(rs.getInt("enum"));     //Employee's Employee ID
                employee[count][3] = rs.getString("dept");                  //Employee's Department
                employee[count][4] = rs.getString("position");              //Employee's Position in Dept
                employee[count][5] = String.valueOf(rs.getInt("class"));    //Employee's Class
                employee[count][6] = String.valueOf(rs.getInt("cashNum"));  //Employee's Cashier Num
                employee[count][7] = String.valueOf(rs.getInt("assNum"));   //Employee's Assistant Num
                employee[count][8] = String.valueOf(rs.getInt("age"));      //Employee's Age
                employee[count][9] = String.valueOf(rs.getDate("dob"));     //Employee's Date of Birth

                count++;
            }
        return employee;
        }catch (SQLException ex) { //Prints Errors When DB Connection Fails
            System.err.println("SQLException: " + ex.getMessage());
            System.err.println("SQLState: " + ex.getSQLState());
            System.err.println("VendorError: " + ex.getErrorCode());
            System.exit(1);
        }
    }catch (SQLException ex) { //Prints Errors When DB Connection Fails
        System.err.println("SQLException: " + ex.getMessage());
        System.err.println("SQLState: " + ex.getSQLState());
        System.err.println("VendorError: " + ex.getErrorCode());
        System.exit(1);
    }
    return null;
}

...以及我希望出现的Progress Bar类并显示进度:

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.image.BufferedImage;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.Dimension;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.JLabel;
import javax.swing.border.TitledBorder;
import java.awt.Font;
import java.awt.Color;
import java.awt.Cursor;

public class ProgressBar extends JFrame {

private JPanel contentPane;
private JPanel pnlProgressBar;

private String title = null;

private ProgressBar progressWindow = this;

private BufferedImage icon;
private JProgressBar progressBar;
private JPanel panel;
private JPanel panel_1;

public static void main(String[] args){
    ProgressBar progressbar = new ProgressBar("TEST");
}

public JProgressBar getProgressBar() {
    return progressBar;
}

public ProgressBar(String title){
    this.title = title;
    mbOSBoot.setLaf();
    initialize();
    setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
    setVisible(true);
}

private void initialize() {
    setTitle("Loading.");
    setPreferredSize(new Dimension(400, 125));
    setLocationRelativeTo(null);
    setBounds(new Rectangle(0, 0, 400, 125));
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    setBounds(100, 100, 400, 125);

    //Animates a Loading... as title of window
    class AnimatedLoading extends TimerTask {
        @Override
        public void run() {
            String currTitle = progressWindow.getTitle();
            switch(currTitle){
            case "Loading.": progressWindow.setTitle("Loading..");
                break;
            case "Loading..": progressWindow.setTitle("Loading...");
                break;
            case "Loading...": progressWindow.setTitle("Loading.");
                break;
            }
        }
    }
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            Timer timer = new Timer();
            timer.scheduleAtFixedRate(new AnimatedLoading(), 0, 1000);
        }
    });
    //End Window Animation

    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);
    {
        pnlProgressBar = new JPanel();
        pnlProgressBar.setBorder(new TitledBorder(null, title, TitledBorder.LEADING, TitledBorder.TOP, null, new Color(59, 59, 59)));
        contentPane.add(pnlProgressBar, BorderLayout.CENTER);
        pnlProgressBar.setLayout(new BorderLayout(0, 0));
        {
            progressBar = new JProgressBar(0,100);
            progressBar.setFont(new Font("SansSerif", Font.BOLD, 13));
            progressBar.setStringPainted(false);
            pnlProgressBar.add(progressBar);
            progressBar.setVisible(true);
        }
        {
            panel = new JPanel();
            pnlProgressBar.add(panel, BorderLayout.NORTH);
        }
        {
            panel_1 = new JPanel();
            pnlProgressBar.add(panel_1, BorderLayout.SOUTH);
        }
    }
}

}

编辑3/26/17

所以,我意识到我遗漏了一些重要的信息......方法getEmps()正被另一个类调用,需要给出结果String[][]来创建GUI。我是否必须在调用getEmps()方法的类中包含有关SwingWorker的所有代码,或者为了组织,我可以在单独的类中执行此操作吗?调用getEmps()方法的代码如下:

        if(SQLDatabase.countRows("SELECT COUNT(*) FROM employee;") == 0){
        JOptionPane.showMessageDialog(null, "No Employees Could Be Found in the Database. If You Believe This is an Error, Please Contact Your Network Administrator");
    }else{
        for(int i = 0; i < SQLDatabase.countRows("SELECT COUNT(*) FROM employee;"); i++){
            String[][] emps = new String[SQLDatabase.countRows("SELECT COUNT(*) FROM employee;")][10];
            emps = SQLDatabase.getEmps();

            EmployeeInfoPanel empInfoPanel = new EmployeeInfoPanel(pnlViewPane, emps, i, title, frmGuiAllEmps);
        }
    }

1 个答案:

答案 0 :(得分:1)

根据建议here,您应该使用SwingWorker在后台检索行。要查看效果,请从此完整example开始。

image

  • 添加JProgressBar

    f.add(model.jpb, BorderLayout.NORTH);
    …
    private static class JDBCModel extends AbstractTableModel {
    
        private final JProgressBar jpb = new JProgressBar();
        …
    }
    
  • 在工作线程启动时设置indeterminate属性:

    JDBCWorker worker = new JDBCWorker();
    jpb.setIndeterminate(true);
    worker.execute();
    
  • 在工作人员done()

    的实施中清除它
    @Override
    protected void done() {
        jpb.setIndeterminate(false);
    }
    

如果您决定显示中间进度,请参阅此相关example