我正在编写一个用于图像分析的Java应用程序,该应用程序有时会打开ImageJ
ImageJ ij = new ImageJ();
并且还会打开一个包含
ImagePlus
的Windows。现在,每当首先关闭
ImageJ
时,按下关闭按钮时ImagePlus
都不会关闭。另一种方法可行,但是在两种情况下,关闭ImageJ
后都会引发异常:java.lang.reflect.InvocationTargetException
at java.awt.EventQueue.invokeAndWait(EventQueue.java:1288)
at java.awt.Window.doDispose(Window.java:1209)
at java.awt.Window.dispose(Window.java:1147)
at ij.ImageJ.run(ImageJ.java:784)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalArgumentException: null source
at java.util.EventObject.<init>(EventObject.java:56)
at java.awt.AWTEvent.<init>(AWTEvent.java:337)
at java.awt.event.InvocationEvent.<init>(InvocationEvent.java:285)
at java.awt.event.InvocationEvent.<init>(InvocationEvent.java:174)
at sun.awt.X11.XBaseMenuWindow.dispose(XBaseMenuWindow.java:907)
...
我不知道这两种情况是否相关。
关于如何强制
ImageJ
关闭所有窗口的任何建议? 最佳答案
例外
在Linux上使用OpenJDK 7时会发生这种情况。 fixed in Java 8是例外。
另外:请注意,该异常并不是您看到的退出问题的真正原因。
处置问题
ImageJ 1.x的应用处置非常混乱。 (有关一些技术讨论,请参见this news post。)它实际上主要是要作为独立的应用程序运行,并且大多在exitWhenQuitting
标志设置为true的情况下进行了测试,以便JVM在关闭主窗口时关闭。因此,以不同的方式使用ImageJ会导致挂起图像窗口也就不足为奇了。
我已经测试了各种解决方法,例如:
ij.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(final WindowEvent e) {
// dispose all image windows
for (final int id : WindowManager.getIDList()) {
final ImagePlus imp = WindowManager.getImage(id);
if (imp == null) continue;
final ImageWindow win = imp.getWindow();
if (win != null) win.dispose();
}
// dispose all other ImageJ windows
for (final Window w : WindowManager.getAllNonImageWindows()) {
w.dispose();
}
}
});
但是它们都不如人们所希望的那样工作。根据上面链接的新闻,我在ImageJ2中完成戒烟工作花了我数周的开发和实验时间。
这是一些使用ImageJ2的代码,几乎可以按照您想要的方式运行:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
import net.imagej.ImageJ;
public class IJDispose {
public static void main(final String... args) {
final ImageJ ij = new ImageJ();
ij.ui().showUI();
final JFrame frame = new JFrame("Hello");
final JButton b = new JButton("Close ImageJ");
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
ij.getContext().dispose();
}
});
frame.getContentPane().add(b);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
启动它后,按Shift + B打开Blobs示例图像。然后从非ImageJ框架中单击“关闭ImageJ”按钮。您会看到ImageJ主窗口和图像窗口按需要进行处置(使用this code from ImageJ Legacy)。
但是,(至少)存在三个问题:
此示例未将
ij.getContext().dispose()
调用与实际的ImageJ1 UI窗口关闭事件挂钩。这样做并不是一件容易的事(我是说,在最近的这段代码中没有做过深入的探讨)。部署ImageJ以及额外的
JFrame
之后,应该关闭JVM。实际上,我们为此付出了很多努力。但这实际上不适用于当前版本的ImageJ,大概是由于某个地方有一些未处理的资源。这是一个错误。在ImageJ主窗口上单击X会关闭整个JVM,因为ImageJ1的
exitWhenQuitting
标志得到set to true。您可以自己将其切换回伪造,但这实际上是棘手的,因为类加载问题与ImageJ2在运行时使用Javassist修补ImageJ1有关。下一个问题是:您真的有多需要这个功能才能工作?
关于java - 如何强制ImageJ关闭所有窗口而没有关闭事件错误?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33543833/