Java 从 SQL 数据库加载时的进度条
Java Progress Bar While Loading From SQL Database
我的目标:从数据库加载时的进度条
我目前正在开发一个日程安排程序,我的一位经理将出于多种目的使用它,但主要是为员工设置每周日程安排。当从远程位置访问 SQL 数据库 时,显然需要一秒钟以上的时间来加载,我想为用户提供一些 反馈 让他们知道程序仍然是 运行。
我真的很想要一个进度条,显示在加载时 table 中已加载的行占总行数的百分比,但我不知道这是否可能.我在想一些不确定的东西,比如 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;
}
...以及我希望出现并显示进度的进度条 class:
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);
}
}
}
}
编辑 2017 年 3 月 26 日
所以,我意识到我遗漏了一些重要信息...方法 getEmps()
正在被另一个 class 调用,需要将结果 String[][]
提供给创建图形用户界面。我是否必须在调用 getEmps()
方法的 class 中包含有关 SwingWorker 等的所有代码,或者为了组织起见,我是否可以在单独的 class 中执行此操作?调用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);
}
}
按照建议 , you should retrieve rows in the background using SwingWorker
. To see the effect, start from this complete 。
添加一个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();
在worker的实现中清除done()
:
@Override
protected void done() {
jpb.setIndeterminate(false);
}
如果您决定显示中间进度,请参阅此相关 example。
我的目标:从数据库加载时的进度条
我目前正在开发一个日程安排程序,我的一位经理将出于多种目的使用它,但主要是为员工设置每周日程安排。当从远程位置访问 SQL 数据库 时,显然需要一秒钟以上的时间来加载,我想为用户提供一些 反馈 让他们知道程序仍然是 运行。
我真的很想要一个进度条,显示在加载时 table 中已加载的行占总行数的百分比,但我不知道这是否可能.我在想一些不确定的东西,比如 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;
}
...以及我希望出现并显示进度的进度条 class:
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);
}
}
}
}
编辑 2017 年 3 月 26 日
所以,我意识到我遗漏了一些重要信息...方法 getEmps()
正在被另一个 class 调用,需要将结果 String[][]
提供给创建图形用户界面。我是否必须在调用 getEmps()
方法的 class 中包含有关 SwingWorker 等的所有代码,或者为了组织起见,我是否可以在单独的 class 中执行此操作?调用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);
}
}
按照建议 SwingWorker
. To see the effect, start from this complete
添加一个
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();
在worker的实现中清除
done()
:@Override protected void done() { jpb.setIndeterminate(false); }
如果您决定显示中间进度,请参阅此相关 example。