ConcurrentModificationException clicking a commander deck list tab outside the Deck Editor
- Dominant language
- Java
- Stars
- 2.7k
- Forks
- 1.1k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 163
Description
**Describe the bug**
Clicking the Commander, Oathbreaker, Brawl or Tiny Leaders tab on any editor
screen other than the Deck Editor throws `ConcurrentModificationException` and
dumps the user on the Deck Editor.
Those tabs should not be on those screens in the first place. Several editors hide the constructed deck list and Deck Gen but leave the four commander lists visible.
**To Reproduce**
1. Make sure the layout still has the deck list tabs. Reset it in Preferences if
not.
2. Home, Settings, Preferences, Token Previewer.
3. Click the Commander tab.
**Expected behavior**
No crash, and no commander deck list tabs in the Token Previewer.
**Desktop**
- OS: macOS
- Version: 2.0.15-SNAPSHOT, master at c8199da
**Stack trace**
java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1096)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:1050)
at forge.gui.framework.DragCell.setSelected(DragCell.java:315)
at forge.gui.framework.SRearrangingUtil.startRearrange(SRearrangingUtil.java:98)
at forge.gui.framework.SRearrangingUtil$1.mousePressed(SRearrangingUtil.java:64)
**Additional context**
`DragCell.setSelected` calls `doc.populate()` inside its loop over `allDocs`.
`VCommanderDecks.populate()` calls `VAllDecks.editPreferredDeck`, which calls
`DeckManager.editDeck`, which calls `openEditor`, which calls
`ensureScreenActive(DECK_EDITOR_CONSTRUCTED)`. On any other screen that really
switches, so `loadLayout` runs `FView.removeAllDragCells()` and clears the list
being iterated.
It does not fire on the Deck Editor itself, where `ensureScreenActive` finds the
screen already active and returns without reloading.
`VAllDecks.populate()` already guards its own call for exactly this reason, with
the comment "editing would switch screens back here". `VCommanderDecks`,
`VOathbreakerDecks`, `VBrawlDecks` and `VTinyLeadersDecks` call it unconditionally.
Separately, `CEditorQuest`, `CEditorQuestCardShop`, `CEditorQuestLimited`,
`CEditorTokenViewer`, `CEditorVariant` and `CEditorWinstonProcess` hide only
`VAllDecks` and `VDeckgen`.
Contributor guide
Assessment
This issue has not been assessed yet.