我正在编写这个Java程序,其中我有一个JFrame和一个线程。一切都很顺利,除了当我单击"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();
}
}
- 退出程序(使用 System.exit() 或 JFrame.EXIT_ON_CLOSE)
- 转到任务管理器并记下进程 ID (pid)
- 打开终端窗口并
cd c:<path>javabin
(将<path>
替换为 Java 安装) - 使用
jstack <pid> | more
.将<pid>
替换为任务管理器中的进程 ID。
查看未标记为"守护程序"的线程。将至少有一个这样的线程挂起并在堆栈跟踪中具有关闭处理程序。
记住这一点,
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
}
});
}
我找到了问题点。问题似乎出现在"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);
}
});
}