最近写了两个GUI小程序,都是和写文件有关的。但是都发现,每次程序运行起来,关闭按钮就不起作用。上了“爆栈”网站和CSDN发了帖,爆栈给出的原因如下,有需要翻译的请留言。
The EDT(Event Dispatch Thread) is responsible for (amongst other things) processing all the UI events that occur, including the request to close your window. But if you block this thread with time consuming tasks (like I/O, loops, Thread#sleep or any other blocking operation), then the EDT is unable to process any of the events accumulating in the queue.
In this case, you best bet would be to use a SwingWorker to off load the writing of the file to another thread. Check out Concurrency in Swing for more information
具体是因为我的写文件操作是在一个button的listener里面触发的,导致读文件操作没完成的时候,线程阻塞了。可以看到按钮是不会反弹回来的。所以再点关闭按钮也就没返回了。
具体解决方法就是要写一个类,继承SwingWorker 类,重写doInBackground()方法,把耗时的写文件操作写在这个方法里面。然后在button的listener里面创建SwingWorker实例,并调用它的execute()方法,即会调用到我们重写的doInBackground()方法。
private class Task extends SwingWorker<Void, Void>{ @Override protected Void doInBackground() throws Exception { //耗时的操作
return null; } }
主方法写法如下
SwingUtilities.invokeLater(new Runnable() { public void run() { try { View window = new View(); window.frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } });
把耗时的操作写在doInBackground()之后,程序运行起来就可以点击关闭按钮了,线程不再阻塞。