0

私は単純なスネークゲームをプログラミングしています。そのため、更新スレッドがあり、無限 while ループを実行します。これにより、すべてのゲームオブジェクトが更新され、JPanel が再描画されます。

// Run thread
public void run () {
    try {
        while (true) {
            this.update();
            this.getGamePanel().sceneShouldRepaint();

            Thread.sleep(this.getFps());
        }
    }
    catch (Exception e) {
        JOptionPane.showMessageDialog(null, e.getMessage(), "Error", JOptionPane.OK_CANCEL_OPTION);
    }
}

さて、問題は、私が呼び出すmyJFrame.repaint()と、おそらく別のスレッドで実行されていることです。そして、ペイントするときは、明らかにオブジェクトの位置、速度などを取得する必要があります...例外paintComponent()がキャッチされていないため、例外が から発生することはわかっています。ご覧のとおり、while ループは try-catch に埋め込まれています。

これについて何ができますか?

例外は次のとおりです。

Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
    at java.util.AbstractList$Itr.next(AbstractList.java:343)
    at ch.ilijatovilo.Scene.GameObjects.Creatures.Snake.Snake.render(Snake.java:52)
    at ch.ilijatovilo.Scene.SceneHandling.Scene.renderSceneObjects(Scene.java:57)
    at ch.ilijatovilo.Scene.SceneHandling.Scene.render(Scene.java:53)
    at ch.ilijatovilo.Scene.SceneHandling.GamePanel.paintComponent(GamePanel.java:53)
    at ch.ilijatovilo.Scene.SceneHandling.GamePanel.paint(GamePanel.java:30)
    at javax.swing.JComponent._paintImmediately(JComponent.java:5106)
    at javax.swing.JComponent.paintImmediately(JComponent.java:4890)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:812)
    at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:714)
    at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:694)
    at javax.swing.RepaintManager.access$700(RepaintManager.java:41)
    at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1672)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:702)
    at java.awt.EventQueue.access$400(EventQueue.java:82)
    at java.awt.EventQueue$2.run(EventQueue.java:663)
    at java.awt.EventQueue$2.run(EventQueue.java:661)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:672)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

ご協力いただきありがとうございます!

ヒント

2 つの異なるスレッドから同時にインスタンスにアクセスしようとすると、ConcurrentModificationException がスローされます。少なくとも私はそれについて聞いたことがあります。

その他のコード

// This is the render method in the Snake class at line 50.
// So 52 is the start of the for loop

public void render(Graphics g) {
    // We delegate the drawing to the body parts
    for (SnakeBodyPart sbp : this.getSnakeBodyParts()) {
        sbp.render(g);
    }

    this.getSnakeHead().render(g);
}

// And here the for loop from the Scene class
protected void renderSceneObjects (Graphics g) {
    for (SceneObject so : this.getSceneObjects()) {
        so.render(g);
    }
} 
4

3 に答える 3

2

ほとんどの場合、このライブラリでは許可されていないように見える別のスレッドでレンダリングする必要がある詳細を変更しています(ほとんどのGUIライブラリではこれが許可されていないと思います)

GUIコンポーネントなどを変更する場合は、SwingUtils.invokeLater()を呼び出す必要があります。これにより、タスクはGUIイベントスレッドで実行され、別のスレッドで同時に実行されることはありません。

于 2012-11-22T15:08:29.173 に答える
1

Well CopyOnWriteArrayList is an answer. I will look after another solution when i have some time ...

Another Solution in awt - Based Application should be

EventQueue.invokeLater(new Runnable() {...});
于 2012-11-23T07:35:31.777 に答える
0

両方のスレッドでリストを調整している場合、言及したような問題が発生します。「Comodification」が見つからない場合は、java.util.concurrent ライブラリに頼ることができます。

http://docs.oracle.com/javase/tutorial/essential/concurrency/collections.html

于 2012-11-22T15:09:30.273 に答える