I have a ProgressMonitor
that shows while I process some database tables. The number of tables is not known at first, so I create the ProgressMonitor
with a maximum value of 100.
Once processing has begun in the SwingWorker
thread, it gets the number of tables and sets the maximum of the ProgressMonitor
to the number of tables (about 530 in my test). However, the ProgressMonitor
still finishes at 100 and stops the execution of the thread, even though the maximum has increased and the progress bar shows 100/530 accurately.
Any idea why this happens?
The actionListener
to start the ProgressMonitor
and SwingWorker
(named TaskThread) from the button press:
public void actionPerformed(ActionEvent e)
{
String cmd = e.getActionCommand();
if (cmd.equals("generate")) {
progressMonitor = new ProgressMonitor(this, "Generating...", "", 0, 100);
task = new TaskThread();
task.addPropertyChangeListener(this);
task.execute();
genButton.setEnabled(false);
}
}
PropertyChangeListener
that updates the ProgressMonitor
:
public void propertyChange(PropertyChangeEvent evt)
{
if ("progress" == evt.getPropertyName() )
{
int progress = (Integer) evt.getNewValue();
progressMonitor.setProgress(progress);
String message = String.format("Completed %d%%.\n", progress);
progressMonitor.setNote(message);
if (progressMonitor.isCanceled() || task.isDone())
{
Toolkit.getDefaultToolkit().beep();
if (progressMonitor.isCanceled()) {
task.cancel(true);
}
genButton.setEnabled(true);
}
}
}
The SwingWorker
class:
class TaskThread extends SwingWorker<Void, Void>
{
@Override
public Void doInBackground()
{
String tableList = tablesArea.getText().trim();
script = "";
String filename = outPath.getText
// Connect to Database
Connection conn = getDbConnection();
if (conn == null)
return null;
try {
// if tableList is blank, get all tables from the From Database afm_tbls table
if (tableList.equals(""))
{
// code omitted
}
}
catch (SQLException se) {
canWriteFile = false;
handleError(se);
}
String[] tables = tableList.split(",");
generateRecordCount(conn, tables);
// Close the connection
if(conn != null)
{
try {
conn.close();
}
catch (Exception ignored) {}
}
// Write SQL code to a file
writeScript(filename);
return null;
}
private void generateRecordCount(Connection conn, String[] tables)
{
setProgressMax(tables.length);
setProgress(0);
// Loop through tables
for (int i = 0; i < tables.length; i++)
{
// Get record count for each table
try {
String sql = "SELECT COUNT(*) AS reccount FROM " + tables[i];
Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery(sql);
rs.next();
int recCount = rs.getInt("reccount");
if (recCount > 0)
script += tables[i] + ": " + recCount + nl;
// Set progress of SwingWorker, ProgressMonitor is updated by PropertyChangeListener
int prog = getProgress() + 1;
setProgress(prog);
}
catch(SQLException se)
{
handleError(se);
}
}
}
}
I figured out why. So hopefully for someone else's benefit, here is the problem:
The SwingWorker.setProgress() function has bounds of 0 and 100, so even though the ProgressMonitor
can handle higher max values, the SwingWorker
thread is ended by an IllegalArgumentException
when the value reaches 101.