ユーザーがボタンをクリックすると、いくつかの作業を行ってから URL にリダイレクトするアプレットを開発しています。GUIがロックアップするのを防ぐためにSwingWorkerを使用しています。
しかし、アプレットを実行すると、ボタンをクリックした後に次のエラーが表示されます。
スレッド「SwingWorker-pool-1-thread-2」での例外 java.lang.IllegalMonitorStateException at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(Unknown Source) at java.util.concurrent.locks.AbstractQueuedSynchronizer.release( java.util.concurrent.locks.ReentrantLock.unlock(不明なソース) で java.util.concurrent.LinkedBlockingQueue.poll(不明なソース) で java.util.concurrent.ThreadPoolExecutor.getTask(不明なソース) でutil.concurrent.ThreadPoolExecutor$Worker.run(不明なソース) で java.lang.Thread.run(不明なソース)
アプレットが自分自身を破壊しているように見えますが、ワーカー スレッドはまだ生きています。Thread.sleep(2000);を追加すると、テストとして、アプレットは正しく動作しますが、それは正しい修正方法ではないと思います。
私が間違っていることは何ですか?? たぶん、メインスレッドからリダイレクトする必要がありますか? アプレットの destroy メソッドは、ワーカー スレッドが終了するまで待機する必要があるのでしょうか。
Java ソース:
public class MyApplet extends javax.swing.JApplet {
class MyWorker extends SwingWorker<Boolean , Void> {
protected Boolean doInBackground() throws Exception {
// DO THE HARD JOB...
}
public void done() {
netscape.javascript.JSObject.getWindow(this).call("onDone", new String[] { "" });
}
}
public void init() {
try {
java.awt.EventQueue.invokeAndWait(new Runnable() {
public void run() {
initComponents();
setBackground(Color.WHITE);
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void jMyButtonctionPerformed(java.awt.event.ActionEvent evt) {
new MyWorker().execute();
}
}
HTML ソース:
<script type="text/javascript">
function onDone(){document.location.href="http://myurl.com";}
</script>