I wonder whether I picked the right forum here, if not, excuse me...
I'm working with NetBeans 6.1 under Mac OS X 10.5.5. (JDK 6) and am building a desktop application. Sometimes, when I have time consuming tasks to do, I simply open a modal JDialog with a progressbar and animated busy-icon (based on the basic stuff Netbeans automatically gives you when choosing a desktop app as a new project type) and start the background task manually in the constructor. This, for instance, looks like this:
public CSaveDialog(java.awt.Frame parent, CDaten d) {
super(parent);
dataObj = d;
initComponents();
// init the progress bar and status icon for
// the swingworker background thread
// creates a new class object. This variable is not used, it just associates task monitors to
// the background tasks. furthermore, by doing this, this class object also animates the
// busy icon and the progress bar of this frame.
CInitStatusBar isb = new CInitStatusBar(statusAnimationLabel, progressBar);
// show status text
msgLabel.setText(resourceMap.getString("msg1"));
// start the background task manually
Task svT = saveFile();
// get the application's context...
ApplicationContext appC = Application.getInstance().getContext();
// ...to get the TaskMonitor and TaskService
TaskMonitor tM = appC.getTaskMonitor();
TaskService tS = appC.getTaskService();
// with these we can execute the task and bring it to the foreground
// i.e. making the animated progressbar and busy icon visible
tS.execute(svT);
tM.setForegroundTask(svT);
}
The background task itself looks like this:
@Action
public Task saveFile() {
return new SaveFileTask(org.jdesktop.application.Application.getInstance(zettelkasten.ZettelkastenApp.class));
}
private class SaveFileTask extends org.jdesktop.application.Task<Object, Void> {
SaveFileTask(org.jdesktop.application.Application app) {
// Runs on the EDT. Copy GUI state that
// doInBackground() depends on from parameters
// to ImportFileTask fields, here.
super(app);
savingTask = this;
}
@Override
protected Object doInBackground() throws IOException {
// Your Task's code here. This method runs
// on a background thread, so don't reference
// the Swing GUI from here.
// prevent task from processing when the file path is incorrect
try {
ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(fp));
XMLOutputter out = new XMLOutputter();
zip.putNextEntry(new ZipEntry("zknFile.xml"));
out.output(dataObj.getZknData(), zip);
zip.putNextEntry(new ZipEntry("authorFile.xml"));
out.output(dataObj.getAuthorData(), zip);
zip.putNextEntry(new ZipEntry("keywordFile.xml"));
out.output(dataObj.getKeywordData(), zip);
zip.close();
}
catch (IOException e) {
e.printStackTrace();
Logger.getLogger(CLoadDialog.class.getName()).log(Level.SEVERE, null, e);
}
return null; // return your result
}
@Override
protected void succeeded(Object result) {
// Runs on the EDT. Update the GUI based on
// the result computed by doInBackground().
}
@Override
protected void finished() {
super.finished();
// when the task is finished, clear it
savingTask = null;
// and close window
dispose();
setVisible(false);
}
}
In this way I have created many JDialogs, so it's all a simple copy'n'paste thing, but only in this case I get an error message, and I don't know why - it might be because I cannot really "decode" the dubug-log and find out what it's telling me. Here the error-message:
26.10.2008 17:24:51 org.jdesktop.application.Task failed
SCHWERWIEGEND: zettelkasten.CSaveDialog$SaveFileTask@bec15c7 failed: java.lang.NullPointerException
java.lang.NullPointerException
at java.io.FileOutputStream.<init>(FileOutputStream.java:172)
at java.io.FileOutputStream.<init>(FileOutputStream.java:131)
at zettelkasten.CSaveDialog$SaveFileTask.doInBackground(CSaveDialog.java:264)
at org.jdesktop.swingworker.SwingWorker$1.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at org.jdesktop.swingworker.SwingWorker.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907)
at java.lang.Thread.run(Thread.java:637)
BUILD SUCCESSFUL (total time: 33 seconds)
The curious thing is, that when I execute the code within the above shown "doInBackground"-method outside a background task, everything works well. Only when I put the method to save XML files and store them in a ZIP file into a background task, the error occurs - although I simply copied'n'pasted the code.
Btw, this is how I open the dialog. I copied this from the "ShowAboutBox", which is a pre-generated source-part of Netbeans:
// opens the Import Dialog. This Class is responsible
// for getting the relevant import data. the import task
// itself (background task) will be started as another dialog,
// when this one is closed
JFrame mainFrame = ZettelkastenApp.getApplication().getMainFrame();
// if dialog window isn't already created, do this now
if (null == saveDlg) {
// get parent und init window
saveDlg = new CSaveDialog(mainFrame,data);
// center window
saveDlg.setLocationRelativeTo(mainFrame);
}
ZettelkastenApp.getApplication().show(saveDlg);
saveDlg.dispose();
saveDlg = null;
Does anyone have an idea?
Thanks in advance
Daniel