4

私は JFrame と Thread を持つこの Java プログラムを書いています。「X」ボタンをクリックしてプログラムを閉じると、プログラム自体が閉じますが(フレームとそのリソースが破壊されます)、「javaw.exe」プロセスは終了しません。私はいつもそれを手動で終了しなければなりません。

もちろん setDefaultCloseOperation(JFrame.*EXIT_ON_CLOSE*) を試しましたが、 System.exit(0) を含む awt ウィンドウリスナーも試しましたが、まだ成功していません。

役立つアイデアはありますか?

これが私のコードです。[JavaCV がマシンにインストールされている必要があります。]

class MyGrabber implements Runnable {
    final int INTERVAL = 1000;// /you may use interval
    IplImage image;
    CanvasFrame frame = new CanvasFrame("Web Cam");

    public MyGrabber() {
        frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
    }

    @Override
    public void run() {
        FrameGrabber grabber = new OpenCVFrameGrabber(0); // 1 for next camera
        int i = 0;
        try {
            grabber.start();

            while (true) {
                image = grabber.grab();
                if (image != null) {
                    cvSaveImage("test.jpg", image);
                    // show image on window
                    frame.showImage(image);
                }
                Thread.sleep(INTERVAL);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (com.googlecode.javacv.FrameGrabber.Exception e) {
            e.printStackTrace();
        }
    }
}

public class TestGrabber {
    public static void main(String[] args) {
        MyGrabber gs = new MyGrabber();
        Thread th = new Thread(gs);
        th.start();
    }
}
4

3 に答える 3

3
  • プログラムを終了します (System.exit() または JFrame.EXIT_ON_CLOSE を使用)。
  • タスクマネージャーに移動し、プロセス ID (pid) をメモします。
  • ターミナル ウィンドウを開きます ( Java インストールcd c:\<path>\java\binに置き換えます)。<path>
  • を使用しjstack <pid> | moreます。<pid>タスク マネージャーのプロセス ID に置き換えます。

「デーモン」としてフラグが立てられていないスレッドを見てください。ハングし、スタック トレースにシャットダウン ハンドラを持つスレッドが少なくとも 1 つ存在します。

于 2012-06-09T13:56:53.940 に答える
3

これを覚えて、

The JVM will terminate only and only when 
All the Non-Daemon threads including the main thread has terminated.

You can try System.exit(0) on the main thread, which runs the main method.

JFrameを拡張して配置するクラスを作成してみてください

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);そのコンストラクターで。

そしてはい..フレームを表示するメインメソッドで、EventQueueを使用します..

例えば:

public static void main(String[] args){
   EventQueue.invokeLater(new Runnable(){

   public void run(){
         myframe.setVisible
        }
   });
 }
于 2012-06-09T13:31:14.290 に答える
2

問題点を見つけたと思います。問題は「grabber.start();」に現れるようです ライン。(その行にコメントを付けることで、すべてがうまくいったからです。これはopenCVライブラリが示す問題です。したがって、この問題を取り除くのはそれほど簡単ではないと思います.

努力してくれてありがとう。

編集: [解決策を見つけた]

OpenCVFrameGrabber クラスに Thread Runnable インターフェースが実装されているようです。したがって、このクラスによって作成されたオブジェクトは、その後スレッドのように実行されます。(同じではありませんが)。とにかく、この問題の解決策として、最初にグラバーをリリースしました。

public Test() {
    //canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
    canvas.addWindowListener(new WindowAdapter() {

        @Override
        public void windowClosing(WindowEvent e) {
            System.out.println("\nClosing it.");
            try {
                //if (grabber != null)
                        grabber.release();
                        //grabber.stop();
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }

            System.exit(0);
        }
    });
}
于 2012-06-09T16:03:23.160 に答える