【发布时间】:2018-08-20 09:24:09
【问题描述】:
在从列表中删除一些对象后尝试重新绘制对象列表时发生异常。通过安全的Collections.removeIf(...) 方法删除项目。 JPanels repaint() 链中发生异常。
重要方法:
public void run() {
isRunning = true;
while (isRunning) {
try {
tick();
repaint();
Thread.sleep(20);
} catch (Exception e) {
isRunning = false;
}
}
}
标记和重绘对象被分成不同的方法,每个方法都包含循环。
private void tick() {
for (THead head : heads) {
head.tick();
}
for (TTail tTail : tails) {
tTail.tick();
}
tail.removeIf(o -> !o.isAlive());
}
如果不再设置 alive 标志,则可能会删除 TTails。
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for (TTail tTail : tails) {
tTail.paint(g2d);
}
for (THead head : heads) {
head.paint(g2d);
}
}
勾选后,所有对象都被重新绘制。这是ConcurrentModificationException 出现的地方。我不明白为什么。它全部在同一个线程中运行,并且没有使用嵌套循环。要删除项目,我使用removeIf 方法,在删除时不更改对象。
另外,THheads 和 TTails 不继承自任何 Swing 超类,因此它们各自的 paint 方法仅使用图形对象执行绘制操作,而不会中断绘制链。
编辑 1:
我现在已经同步访问了 pos 对象,在 paint() 和 tick() 中都可以访问。
public abstract class TPanelObject {
private Point pos;
private Object lock = new Object();
public Point getPos() {
synchronized (lock) {
return pos;
}
}
public void setPos(Point pos) {
synchronized (lock) {
this.pos = pos;
}
}
}
除了图形对象本身之外,它是操作过程中唯一被操纵的对象。
也许我需要让TPanelObject 从JComponent 继承并将对象添加到面板本身。异常可能是由对 Graphics 对象的访问引起的,因为它在重绘时不再有效?
【问题讨论】:
-
尝试
TTail tTail : new ArrayList( tails )对集合的副本进行迭代,避免在对集合进行迭代时修改集合引起的异常。