我目前正在制定计划程序,我的一位经理会将其用于多种用途,但主要是为员工设置每周计划。当从远程位置访问 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);
}
}
}
}
所以,我意识到我遗漏了一些重要的信息......方法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);
}
}
答案 0 :(得分:1)
根据建议here,您应该使用SwingWorker
在后台检索行。要查看效果,请从此完整example开始。
添加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。