Skip to content

Fix: exception dialog shows up when moving sidepanel down/up#15248

Merged
calixtus merged 5 commits intoJabRef:mainfrom
pluto-han:fix-for-issue-15207
Mar 2, 2026
Merged

Fix: exception dialog shows up when moving sidepanel down/up#15248
calixtus merged 5 commits intoJabRef:mainfrom
pluto-han:fix-for-issue-15207

Conversation

@pluto-han
Copy link
Copy Markdown
Contributor

Related issues and pull requests

Closes #15207

PR Description

The default constructor SidePanePreferences() used Map.of() which creates immutable map. Add or modify will throw an exception. I copied the map into mutable EnumMap.

Required verification screenshot:
image

Steps to test

  1. Tick Tool -> Web search & groups. Now sidepane has two views.
image
  1. Click either move panel down from "Web search" or move panel up from "Groups"

  2. Works good, no exception dialog shows up.

image

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • I manually tested my changes in running JabRef (always required)
  • [/] I added JUnit tests for changes (if applicable)
  • I added screenshots in the PR description (if change is visible to the user)
  • I added a screenshot in the PR description showing a library with a single entry with me as author and as title the issue number
  • I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

@qodo-free-for-open-source-projects
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Fix exception dialog when moving side panels

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Fixed exception when moving side panels up/down by using mutable collections
• Replaced immutable Map.of() with mutable EnumMap in constructor
• Converted input collections to mutable EnumSet and EnumMap before wrapping
• Updated CHANGELOG.md with fix description
Diagram
flowchart LR
  A["Immutable Map/Set<br/>from Map.of()"] -->|Issue: Cannot modify| B["Exception thrown<br/>on add/modify"]
  C["Mutable EnumMap<br/>and EnumSet"] -->|Solution: Copy to mutable| D["FXCollections.observableMap<br/>observableSet"]
  D -->|Result: Works correctly| E["Side panels move<br/>without errors"]
Loading

Grey Divider

File Changes

1. jabgui/src/main/java/org/jabref/gui/frame/SidePanePreferences.java 🐞 Bug fix +8/-2

Convert immutable collections to mutable before wrapping

• Added import for EnumMap utility class
• Modified constructor to convert input collections to mutable EnumSet and EnumMap before
 wrapping with FXCollections
• Ensures observable collections wrap mutable underlying collections instead of immutable ones

jabgui/src/main/java/org/jabref/gui/frame/SidePanePreferences.java


2. CHANGELOG.md 📝 Documentation +1/-0

Document side panel movement exception fix

• Added entry documenting the fix for exception dialog when moving side panels
• References issue #15207

CHANGELOG.md


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects
Copy link
Copy Markdown
Contributor

qodo-free-for-open-source-projects bot commented Mar 1, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (1) 📎 Requirement gaps (0)

Grey Divider


Remediation recommended

1. Awkward CHANGELOG wording📘 Rule violation ✓ Correctness
Description
The new CHANGELOG entry contains grammatically incorrect/awkward phrasing (will show up) and
imprecise wording (side panels down/up) in user-facing text. This reduces clarity and
professionalism of release notes.
Code

CHANGELOG.md[29]

+- We fixed an issue where exception dialog will show up when moving side panels down/up. [#15207](https://github.com/JabRef/jabref/issues/15207)
Evidence
PR Compliance ID 33 requires user-facing text to be typo-free and grammatically correct; the added
CHANGELOG bullet contains awkward grammar and unclear phrasing.

CHANGELOG.md[29-29]
Best Practice: Learned patterns

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The CHANGELOG entry added in this PR is user-facing but has awkward/incorrect grammar (e.g., `will show up`) and imprecise phrasing (`down/up`, `side panels`).
## Issue Context
Compliance requires user-facing text (including CHANGELOG entries) to be typo-free, grammatically correct, and precise.
## Fix Focus Areas
- CHANGELOG.md[29-29]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. No regression test added 🐞 Bug ⛯ Reliability
Description
This change fixes a crash path caused by default preferences using an immutable Map.of(), but
there is no unit test ensuring SidePanePreferences.getDefault().getPreferredPositions() remains
mutable and pane reordering doesn’t throw. Without coverage, a future refactor could reintroduce the
immutable backing map and bring back the exception dialog.
Code

jabgui/src/main/java/org/jabref/gui/frame/SidePanePreferences.java[R24-30]

+        EnumSet<SidePaneType> mutableVisiblePanes = EnumSet.noneOf(SidePaneType.class);
+        mutableVisiblePanes.addAll(visiblePanes);
+        EnumMap<SidePaneType, Integer> mutablePreferredPositions = new EnumMap<>(SidePaneType.class);
+        mutablePreferredPositions.putAll(preferredPositions);
+
+        this.visiblePanes = FXCollections.observableSet(mutableVisiblePanes);
+        this.preferredPositions = FXCollections.observableMap(mutablePreferredPositions);
Evidence
The default preferences constructor passes Map.of() for preferred positions, and the side pane
move logic persists new ordering via setPreferredPositions, which performs clear()/putAll()
mutations. If the observable map wraps an immutable backing map (the original bug), these mutations
throw; current tests construct SidePanePreferences with mutable HashMap/HashSet and therefore
don’t cover the default Map.of() scenario.

jabgui/src/main/java/org/jabref/gui/frame/SidePanePreferences.java[34-40]
jabgui/src/main/java/org/jabref/gui/sidepane/SidePaneViewModel.java[114-119]
jabgui/src/main/java/org/jabref/gui/frame/SidePanePreferences.java[59-62]
jabgui/src/test/java/org/jabref/gui/sidepane/SidePaneViewModelTest.java[53-67]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The fix prevents exceptions caused by wrapping an immutable `Map.of()` inside a JavaFX `ObservableMap`, but there is no regression test ensuring this default-preferences path stays safe.
## Issue Context
- `SidePanePreferences.getDefault()` still passes `Map.of()`.
- Reordering panes triggers `SidePaneViewModel.updatePreferredPositions()` which calls `SidePanePreferences.setPreferredPositions()`, performing `clear()`/`putAll()` on the observable map.
- A test should fail if the backing map becomes immutable again.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/frame/SidePanePreferences.java[21-40]
- jabgui/src/main/java/org/jabref/gui/frame/SidePanePreferences.java[59-62]
- jabgui/src/main/java/org/jabref/gui/sidepane/SidePaneViewModel.java[114-149]
- jabgui/src/test/java/org/jabref/gui/sidepane/SidePaneViewModelTest.java[53-113]
## Suggested test approach
1. Create `SidePanePreferences prefs = SidePanePreferences.getDefault();`
2. Wire it into a `SidePaneViewModel` (similar to `SidePaneViewModelTest`) and set up at least two panes.
3. Call `moveUp`/`moveDown` and assert:
- no exception is thrown
- `prefs.getPreferredPositions()` contains updated indices
Alternatively, a smaller unit test can assert mutability directly:
- `SidePanePreferences.getDefault().getPreferredPositions().put(SidePaneType.GROUPS, 0)` does not throw.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@testlens-app

This comment has been minimized.

Co-authored-by: Christoph <siedlerkiller@gmail.com>
@testlens-app

This comment has been minimized.

@testlens-app

This comment has been minimized.

@calixtus calixtus enabled auto-merge March 2, 2026 20:20
@testlens-app
Copy link
Copy Markdown

testlens-app bot commented Mar 2, 2026

✅ All tests passed ✅

🏷️ Commit: 7b927fe
▶️ Tests: 11252 executed
⚪️ Checks: 51/51 completed


Learn more about TestLens at testlens.app.

@calixtus calixtus added this pull request to the merge queue Mar 2, 2026
@github-actions github-actions bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Mar 2, 2026
Merged via the queue into JabRef:main with commit 2d1f4ff Mar 2, 2026
51 checks passed
priyanshu16095 pushed a commit to priyanshu16095/jabref that referenced this pull request Mar 3, 2026
…15248)

* fix exception dialog when moving panel down/up

* update CHANGELOG.md

* Apply suggestion from @Siedlerchr

Co-authored-by: Christoph <siedlerkiller@gmail.com>

* Stylistic change

---------

Co-authored-by: Christoph <siedlerkiller@gmail.com>
Co-authored-by: Carl Christian Snethlage <calixtus@users.noreply.github.com>
Co-authored-by: Carl Christian Snethlage <50491877+calixtus@users.noreply.github.com>
Siedlerchr added a commit that referenced this pull request Mar 5, 2026
…rg.openrewrite.recipe-rewrite-recipe-bom-3.25.0

* upstream/main: (35 commits)
  Chore: add dependency-management.md (#15278)
  Chore(deps): Bump dev.langchain4j:langchain4j-bom in /versions (#15277)
  New Crowdin updates (#15274)
  Chore(deps): Bump actions/upload-artifact from 6 to 7 (#15271)
  Chore(deps): Bump actions/download-artifact from 7 to 8 (#15270)
  Chore(deps): Bump docker/login-action from 3 to 4 (#15268)
  Fix threading issues in citations relations tab (#15233)
  Fix: Citavi XML importer now preserves citation keys (#14658) (#15257)
  Preserve no break spaces in Latex to Unicode conversion (#15174)
  Fix: open javafx.scene.control.skin to controlsfx (#15260)
  Reduce complexity in dependencies setup (restore) (#15194)
  New translations jabref_en.properties (French) (#15256)
  Fix: exception dialog shows up when moving sidepanel down/up (#15248)
  Implement reset for Name Display Preferences (#15136)
  Chore(deps): Bump net.bytebuddy:byte-buddy in /versions (#15252)
  Chore(deps): Bump io.zonky.test.postgres:embedded-postgres-binaries-bom (#15253)
  Chore(deps): Bump io.zonky.test:embedded-postgres in /versions (#15254)
  Chore(deps): Bump net.ltgt.errorprone from 5.0.0 to 5.1.0 in /jablib (#15251)
  New Crowdin updates (#15247)
  Refined the "Select files to import" page in "Search for unlinked local files" dialog (#15110)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: no-bot-comments status: to-be-merged PRs which are accepted and should go into the merge-queue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UnsupportedOperationException when clicking “Move panel up” in Groups panel

3 participants