我有以下代码,只是得到了ConcurrentModificationException。
fchProtocol = new FileChooser(lastFileLoc);
FileNameExtensionFilter xmlfilter = new FileNameExtensionFilter("xml files (*.xml)", "xml");
fchProtocol.setFileFilter(xmlfilter); <<<< ***** exception from here
异常跟踪信息:
java.util.ConcurrentModificationException
java.util.Vector$Itr.checkForComodification(Vector.java:1184)
java.util.Vector$Itr.next(Vector.java:1137)
javax.swing.plaf.basic.BasicDirectoryModel$LoadFilesThread.cancelRunnables(BasicDirectoryModel.java:340)
javax.swing.plaf.basic.BasicDirectoryModel$LoadFilesThread.cancelRunnables(BasicDirectoryModel.java:346)
javax.swing.plaf.basic.BasicDirectoryModel.validateFileCache(BasicDirectoryModel.java:135)
javax.swing.plaf.basic.BasicDirectoryModel.propertyChange(BasicDirectoryModel.java:69)
java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335)
java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:327)
java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263)
java.awt.Component.firePropertyChange(Component.java:8422)
javax.swing.JFileChooser.setFileFilter(JFileChooser.java:1473)
这是Java API方法代码。这是最后一行抛出异常。
public void setFileFilter(FileFilter filter) {
FileFilter oldValue = fileFilter;
fileFilter = filter;
if (filter != null) {
if (isMultiSelectionEnabled() && selectedFiles != null && selectedFiles.length > 0) {
Vector<File> fList = new Vector<File>();
boolean failed = false;
for (File file : selectedFiles) {
if (filter.accept(file)) {
fList.add(file);
} else {
failed = true;
}
}
if (failed) {
setSelectedFiles((fList.size() == 0) ? null : fList.toArray(new File[fList.size()]));
}
} else if (selectedFile != null && !filter.accept(selectedFile)) {
setSelectedFile(null);
}
}
firePropertyChange(FILE_FILTER_CHANGED_PROPERTY, oldValue, fileFilter);
}
这发生在GUI初始化阶段。 xmlfileter 是一个局部变量。
我在Linux中使用 javaVersion = 1.8.0_20 。它不可重复,在我的开发过程中今年只发生了三次。
我不知道如何避免这种情况,或者如何正确使用FileChooser及其FileFilter。有人可以帮帮我吗?
修改
它发生在应用程序初始化阶段:
SwingUtilities.invokeAndWait(new Runnable()
public void run()
{
initalize GUI classes from here
}
);
进行GUI初始化,但在最初的几个步骤中,GUI初始化线程失败了。 GUI初始化线程中没有其他线程。而且主线程也无法访问GUI初始化线程。
基本时刻有两个线程:主线程和GUI初始化线程通过invorkAndWait()调用启动。
答案 0 :(得分:1)
如果你在事件调度线程之外的其他线程上执行GUI工作,这种事情一直在Swing中发生。特别是&#34;不可重现&#34;是一个线索。并发线程正在处理GUI是一个时间问题,而只有EDT应该这样做。有关详细信息,请参阅here。
因此,在您的情况下,在SwingUtilities.invokeLater
中包装与GUI相关的内容:
final FileFilter oldValue = fileFilter;
...
SwingUtilities.invokeLater(new Runnable() {
public void run() {
firePropertyChange(FILE_FILTER_CHANGED_PROPERTY, oldValue, fileFilter);
}
});
答案 1 :(得分:0)
不是一个真正的答案,但可能对其他人提出这个问题很有用。
这绝对是2014年https://bugs.openjdk.java.net/browse/JDK-8068244的一种表现。只是在Java 9.0.1 / Windows 10中发生,在JFrame构造函数中抛出EDT,与OP描述的非常类似。
java.util.ConcurrentModificationException
at java.base/java.util.Vector$Itr.checkForComodification(Unknown Source)
at java.base/java.util.Vector$Itr.next(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicDirectoryModel$FilesLoader.cancelRunnables(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicDirectoryModel$FilesLoader.cancelRunnables(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicDirectoryModel.validateFileCache(Unknown Source)
at java.desktop/javax.swing.plaf.basic.BasicDirectoryModel.propertyChange(Unknown Source)
at java.desktop/java.beans.PropertyChangeSupport.fire(Unknown Source)
at java.desktop/java.beans.PropertyChangeSupport.firePropertyChange(Unknown Source)
at java.desktop/java.beans.PropertyChangeSupport.firePropertyChange(Unknown Source)
at java.desktop/java.awt.Component.firePropertyChange(Unknown Source)
at java.desktop/javax.swing.JFileChooser.setFileFilter(Unknown Source)
at com.example.ExampleJFrame.initFileChoosers(Unknown Source)
at com.example.ExampleJFrame.<init>(Unknown Source)
at com.example.ExampleJFrame$15.run(Unknown Source)
at java.desktop/java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.desktop/java.awt.EventQueue.access$500(Unknown Source)
at java.desktop/java.awt.EventQueue$3.run(Unknown Source)
at java.desktop/java.awt.EventQueue$3.run(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
导致它的代码在EDT上通过SwingUtilities.invokeLater()
正确执行,如堆栈跟踪中所示。 initFileChoosers()
方法仅实例化几个文件选择器,为它们调用setFileFilter()
,有时按顺序多次调用。
当然不能复制。