Here is code that I have used in one form another for close to a decade. It is also used in releases of ImageProcessorPro and CSX so it has been fairly well vetted.
//
// Function: createProgressPalette
// Description: Opens up a palette window with a progress bar that can be
// 'asynchronously' while the script continues running
// Input:
// title the window title
// min the minimum value for the progress bar
// max the maximum value for the progress bar
// parent the parent ScriptUI window (opt)
// useCancel flag for having a Cancel button (opt)
// msg message that can be displayed and changed in the palette (opt)
//
// onCancel This method will be called when the Cancel button is pressed.
// This method should return 'true' to close the progress window
// Return: The palette window
//
function createProgressPalette(title, min, max,
parent, useCancel, msg) {
var opts = {
closeButton: false,
maximizeButton: false,
minimizeButton: false
};
var win = new Window('palette', title, undefined, opts);
win.bar = win.add('progressbar', undefined, min, max);
if (msg) {
win.msg = win.add('statictext');
win.msg.text = msg;
}
win.bar.preferredSize = [500, 20];
win.parentWin = undefined;
win.recenter = false;
win.isDone = false;
if (parent) {
if (parent instanceof Window) {
win.parentWin = parent;
} else if (useCancel == undefined) {
useCancel = !!parent;
}
}
if (useCancel) {
win.onCancel = function() {
this.isDone = true;
return true; // return 'true' to close the window
};
win.cancel = win.add('button', undefined, localize("$$$/JavaScripts/psx/Cancel=Cancel"));
win.cancel.onClick = function() {
var win = this.parent;
try {
win.isDone = true;
if (win.onCancel) {
var rc = win.onCancel();
if (rc != false) {
if (!win.onClose || win.onClose()) {
win.close();
}
}
} else {
if (!win.onClose || win.onClose()) {
win.close();
}
}
} catch (e) {
LogFile.logException(e, '', true);
}
};
}
win.onClose = function() {
this.isDone = true;
return true;
};
win.updateProgress = function(val) {
var win = this;
if (val != undefined) {
win.bar.value = val;
}
// else {
// win.bar.value++;
// }
if (win.recenter) {
win.center(win.parentWin);
}
win.update();
win.show();
// win.hide();
// win.show();
};
win.recenter = true;
win.center(win.parent);
return win;
};