2012-06-09 53 views
4

我在寫這個Java程序,其中有一個JFrame和一個線程。 一切都很好,除了當我點擊'X'按鈕關閉程序,程序本身關閉(框架和它的資源被破壞),但「javaw.exe」過程不會結束。我必須始終手動終止。我試過了setDefaultCloseOperation(JFrame。* EXIT_ON_CLOSE *),我甚至嘗試過帶有System.exit(0)的awt窗口監聽器,但仍然沒有成功。「javaw.exe」在System.exit之後不會退出(0)

任何想法,以幫助?

這是我的代碼。 [它需要你的機器上安裝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(); 
    } 
} 
+3

您可能需要向我們提供更多信息。如果您很快就不能獲得體面的解決方案,請考慮創建併發布[SSCCE](http://SSCCE.org)。 –

+0

更多信息?像什麼?什麼是不可理解的? – Emil

+2

我不明白是什麼導致你目前的問題,並擔心這是因爲你發佈的代碼與當前問題無關。如果我把你的代碼放在上面,按摩它以便編譯和運行,但它不會重現問題。所以這對我意味着這個問題可能在代碼的其他地方未顯示。我們沒有時間或意願來審覈所有的代碼,但如果這是我的項目,我會嘗試將代碼分解到最少的可編譯和可運行代碼,這實際上證明了問題。然後我會在這裏發佈。 –

回答

1

我想我找到了問題點。這個問題似乎出現在「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); 
     } 
    }); 
} 
+1

你不應該從不同的線程訪問FrameGrabber,它不能保證線程安全。你應該從你調用start()和grab()的同一線程調用grabber.stop()/ release()。然後該過程應該正常退出。 –

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 
     } 
    }); 
} 
+1

我認爲'System.exit(...)'實際上會停止非守護線程,這就是爲什麼我沒有發佈答案。我認爲@bestsss有更好的主意。 –

+0

不,沒有幫助。 – Emil

2
  • 退出程序(使用System.exit()的或JFrame.EXIT_ON_CLOSE)
  • 轉到任務管理器,並注意該過程ID(PID)
  • 打開一個終端窗口和cd c:\<path>\java\bin(喲替換<path> ur Java安裝)
  • 使用jstack <pid> | more。將<pid>替換爲任務管理器中的進程標識。

看看沒有標記爲「守護進程」的線程。至少會有一個這樣的線程在堆棧跟蹤中掛起並具有關閉處理程序。

+0

而且?所以?該怎麼辦? – Emil

+0

@Emil,這將顯示問題。如果問題不明確,請發佈輸出。 –

+0

@HendrikBrummermann謝謝你,讓我看着正確的方向! – Kingsolmn

相關問題