3

閉じたときにJFrame停止するコードがあります。SwingWorker

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.SwingWorker;
import javax.swing.WindowConstants;

/**
 *
 * @author yccheok
 */
public class JavaApplication11 extends JFrame {

    public JavaApplication11() {
        this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        final Task task = new Task();
        task.execute();
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                if (task != null) {
                    task.cancel(true);
                }
            }           
        }); 
    }

    public class Task extends SwingWorker<Void, Void> {

        @Override
        protected Void doInBackground() {
            for (int i = 0; i < 1000; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    System.out.println("interrupted in doInBackground");
                    break;
                }
                System.out.println("-> " + i);
            }
            return null;
        }

        @Override
        public void done() {
            System.out.println("DONE!!!");
        }        
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new JavaApplication11().setVisible(true);
    }
}

しかし、ランダムに、 を閉じるとJFrameSwingWorkerdoneメソッドdoInBackgroundが終了する前に実行されていることに気付きます。(問題を発生させるには、上記の JFrame を数回実行する必要があります)

-> 0
-> 1
-> 2
-> 3
-> 4
DONE!!!
interrupted in doInBackground

なぜそうなのか、私は知っていますか?

4

1 に答える 1

2

ハワードのコメントから、http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6826514は、これがバグである可能性があることを示しています。

私もこれに遭遇しました。doInBackground順序に依存する場合は、クリーンアップを内部に配置する傾向がありdone、例外処理にのみ使用します。

@Override
protected Void doInBackground() {
    try {
        // ...
    } finally {
        // some cleanup inside 'doInBackground'
        if (isCancelled()) {
            // ...
        } else {
            // ...
        }
    }
    return (Void) null;
}
@Override
protected void done() {
    try {
        get();
    } catch (CancellationException x) {
        // ...
    } catch (InterruptedException x) {
        // ...
    } catch (ExecutionException x) {
        // ...
    }
}

invokeLater(から GUI を更新する必要がある場合は、忘れずに使用してくださいdoInBackground。)

私の場合、次のようなものがありました。

  • doInBackground「ファイルを開く」ルーチンを実行し、Swing コンポーネントを定期的に作成して GUI に追加します。
  • キャンセルすると (Cancelボタン付きのプログレス バー ダイアログを介して)、 でdone作成されたすべてのコンポーネントが削除されdoInBackgroundます。

これらのアクションが重なって、ワイプの実行doInBackground後にコンポーネントの作成が続行されることがありました。ユーザーにとっては、デバッグが呼び出されていることを示していることを除いて、done押すことが時々機能しないように見えます。のこの動作を除いて、他の説明はありませんでした。CanceldoneSwingWorker

于 2013-10-17T21:09:25.007 に答える