【发布时间】:2015-07-11 20:50:02
【问题描述】:
我使用 SWING API 编写了一个 GUI。
我得到了一组表单,每个表单都帮助用户创建一个预定义类型的对象。完成后,用户通过单击JButton 来确认创建。
我有一个遵循单例模式的类 (DataManager)。此外,该类遵循观察者和工厂模式。 DataManager 是一个可观察的对象。观察到的数据格式如下:
public static List<Target> targets = new ArrayList<Target>();
DataManager 类包含一组方法来创建对象的预定义类型。
示例:
public static final void createTarget(String id, double x, double y, double z){
targets.add(new Target(id,x,y,z));
notifyTargetObservers();
}
其中一种形式是观察者对象,它观察 DataManager 以了解其列表中保存的任何数据的更新(例如列表目标...)。
IObserve:
public interface IObserve {
public void updateTargets();
public void updateSources();
public void updateFluids();
}
观察者实现IObserver中介绍的方法。
示例:
@Override
public void updateTargets(){
cbAnalysisTargets.addItem(DataManager.targets.get(DataManager.targets.size()-1));
}
cbAnalysisTargets 是一个 JComboBox,需要在将新对象引入环境时动态更新。
IObservable:
public abstract class IObservable {
private static Set<IObserve> targetObservers = new HashSet<IObserve>();
private static Set<IObserve> sourceObservers = new HashSet<IObserve>();
private static Set<IObserve> fluidObservers = new HashSet<IObserve>();
public final void addTargetObserver(IObserve o){
targetObservers.add(o);
}
public final void addSourceObserver(IObserve o){
sourceObservers.add(o);
}
public final void addFluidObserver(IObserve o){
fluidObservers.add(o);
}
public static final void notifyTargetObservers(){
for(IObserve observer : targetObservers){
observer.updateTargets();
}
}
public static final void notifySourceObservers(){
for(IObserve observer : sourceObservers){
observer.updateSources();
}
}
public static final void notifyFluidObservers(){
for(IObserve observer : fluidObservers){
observer.updateFluids();
}
}
}
问题在于 IndexOutOfBounds 异常。在以下情况下会出现异常:
1.用户打开第一个表单,成功发起创建2个相同类型的预定义对象。
2、用户打开第二个表单;填写表格并在确认后(单击按钮)收到如下异常。
理想情况下,我希望在解决以下问题和解决下面所述的异常方面得到帮助。
例外:
线程“AWT-EventQueue-0”java.lang.IndexOutOfBoundsException 中的异常:索引:1,大小:1 在 java.util.ArrayList.rangeCheck(未知来源) 在 java.util.ArrayList.get(未知来源) 在 fprof.application.data.frame.manager.content.AnalysisCreatorPanel.updateSources(AnalysisCreatorPanel.java:99) 在 fprof.application.utility.IObservable.notifySourceObservers(IObservable.java:32) 在 fprof.application.data.manager.IDataManager.createSource(IDataManager.java:29) 在 fprof.application.data.frame.manager.content.SourceCreatorPanel$1.actionPerformed(SourceCreatorPanel.java:127) 在 javax.swing.AbstractButton.fireActionPerformed(未知来源) 在 javax.swing.AbstractButton$Handler.actionPerformed(未知来源) 在 javax.swing.DefaultButtonModel.fireActionPerformed(未知来源) 在 javax.swing.DefaultButtonModel.setPressed(未知来源) 在 javax.swing.plaf.basic.BasicButtonListener.mouseReleased(未知来源) 在 java.awt.Component.processMouseEvent(未知来源) 在 javax.swing.JComponent.processMouseEvent(未知来源) 在 java.awt.Component.processEvent(未知来源) 在 java.awt.Container.processEvent(未知来源) 在 java.awt.Component.dispatchEventImpl(未知来源) 在 java.awt.Container.dispatchEventImpl(未知来源) 在 java.awt.Component.dispatchEvent(未知来源) 在 java.awt.LightweightDispatcher.retargetMouseEvent(未知来源) 在 java.awt.LightweightDispatcher.processMouseEvent(未知来源) 在 java.awt.LightweightDispatcher.dispatchEvent(未知来源) 在 java.awt.Container.dispatchEventImpl(未知来源) 在 java.awt.Window.dispatchEventImpl(未知来源) 在 java.awt.Component.dispatchEvent(未知来源) 在 java.awt.EventQueue.dispatchEventImpl(未知来源) 在 java.awt.EventQueue.access$500(未知来源) 在 java.awt.EventQueue$3.run(未知来源) 在 java.awt.EventQueue$3.run(未知来源) 在 java.security.AccessController.doPrivileged(本机方法) 在 java.security.ProtectionDomain$1.doIntersectionPrivilege(未知来源) 在 java.security.ProtectionDomain$1.doIntersectionPrivilege(未知来源) 在 java.awt.EventQueue$4.run(未知来源) 在 java.awt.EventQueue$4.run(未知来源) 在 java.security.AccessController.doPrivileged(本机方法) 在 java.security.ProtectionDomain$1.doIntersectionPrivilege(未知来源) 在 java.awt.EventQueue.dispatchEvent(未知来源) 在 java.awt.EventDispatchThread.pumpOneEventForFilters(未知来源) 在 java.awt.EventDispatchThread.pumpEventsForFilter(未知来源) 在 java.awt.EventDispatchThread.pumpEventsForHierarchy(未知来源) 在 java.awt.EventDispatchThread.pumpEvents(未知来源) 在 java.awt.EventDispatchThread.pumpEvents(未知来源) 在 java.awt.EventDispatchThread.run(未知来源)
编辑 1: updateSource 方法:
@Override
public void updateSources(){
cbAnalysisSources.addItem(DataManager.sources.get(DataManager.sources.size()-1));
}
【问题讨论】: