Skip to content

Sync new-field hint with auto-completion popup in JumpToFieldDialog - #17101

Open
adeifv wants to merge 15 commits into
JabRef:mainfrom
adeifv:Jump-to-field-dialog-ui
Open

adeifv wants to merge 15 commits into
JabRef:mainfrom
adeifv:Jump-to-field-dialog-ui

Conversation

@adeifv

@adeifv adeifv commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Summary

In the "Jump to field" dialog, the "Field will be created" hint was driven only by the raw typed text, so it stayed visible even while the auto-completion popup selected an existing field (e.g. typing t with title highlighted).

The hint now follows the highlighted suggestion:

  • it disappears whenever an existing field is highlighted.
  • it appears exactly when confirming would create a new field.
  • When nothing is highlighted (popup dismissed), it falls back to the typed text.

jabref-contrib-policy:4.2:reviewed:ok

Steps to test

  1. Open any library and select an entry in the entry editor.
  2. Press Ctrl+J to open the "Jump to field" dialog.
  3. Type t and wait for the auto-completion popup; select title.
  4. Confirm: the "Field will be created" hint is hidden while the popup is open.
  5. Type a non-existent field name, e.g. custom, the hint shows again.
Screencast.from.2026-09-11.23-23-03.webm

Related issues and pull requests

Closes #17060, Follow-up #16639

AI usage

antigravity/claude sonnet 4.6, All changes were reviewed and verified by the contributor


Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • If AI tools were used, I disclosed them in the "AI usage" section and reviewed, understood, and take full ownership of all AI-generated code
  • 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 one sentence (max 20 words) to CHANGELOG.md describing the change from the user's point of view (if the 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

PR Summary by Qodo

Sync jump-to-field hint with highlighted completion

🐞 Bug fix ✨ Enhancement 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Synchronizes the creation hint with the highlighted field suggestion.
• Adds mouse-hover selection and robust popup lifecycle tracking.
• Resizes the dialog when hint visibility changes and documents the fix.
Diagram

graph TD
  Input["Typed input"] --> Dialog["Jump dialog"] --> Binding["Hover binding"] --> Popup["ControlsFX popup"]
  Popup -->|highlight| Binding -->|selection| Dialog -->|validate| ViewModel["Field check"] --> Hint["Creation hint"]
  Dialog -->|confirm| Editor["Entry editor"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Build a public-API JavaFX completion popup
  • ➕ Avoids compatibility risks from ControlsFX implementation classes
  • ➕ Provides complete control over highlighting and popup lifecycle
  • ➖ Requires substantially more popup positioning, focus, keyboard, and accessibility code
  • ➖ Duplicates behavior already supplied by ControlsFX
2. Add highlight support upstream in ControlsFX
  • ➕ Creates a reusable public API without internal skin access
  • ➕ Reduces long-term maintenance for JabRef and other consumers
  • ➖ Depends on external acceptance and release timing
  • ➖ Cannot deliver the dialog fix immediately

Recommendation: The current custom binding is a pragmatic, contained fix because it preserves established ControlsFX completion behavior while exposing the required selection state. Keep the explicit compatibility warning and canary test; a public ControlsFX API or upstream enhancement would be preferable if this pattern expands beyond this dialog.

Files changed (5) +288 / -16

Enhancement (2) +135 / -1
HoverSelectingAutoCompletionBinding.javaAdd hover-aware ControlsFX auto-completion binding +134/-0

Add hover-aware ControlsFX auto-completion binding

• Introduces a reusable auto-completion binding that exposes popup visibility and the keyboard- or mouse-highlighted suggestion. It installs a hover-selecting popup skin, prevents completion from reopening the popup, and removes registered listeners when disposed.

jabgui/src/main/java/org/jabref/gui/util/HoverSelectingAutoCompletionBinding.java

JumpToFieldDialog.fxmlPosition the creation hint above the search field +1/-1

Position the creation hint above the search field

• Reorders the dialog controls so the dynamically visible creation hint appears before the field input.

jabgui/src/main/resources/org/jabref/gui/entryeditor/JumpToFieldDialog.fxml

Bug fix (1) +103 / -15
JumpToFieldDialog.javaDrive field hint and confirmation from the highlighted suggestion +103/-15

Drive field hint and confirmation from the highlighted suggestion

• Replaces the standard completion binding with hover-aware completion and tracks the effective suggestion across popup generations. The dialog now derives hint visibility and confirmation from the highlighted suggestion, falls back to typed text when appropriate, filters blank suggestions, and resizes when the hint changes.

jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java

Tests (1) +49 / -0
HoverSelectingAutoCompletionBindingTest.javaGuard ControlsFX popup skin assumptions +49/-0

Guard ControlsFX popup skin assumptions

• Adds a JavaFX canary test verifying that the ControlsFX popup skin still exposes its suggestion ListView. This detects dependency changes that would invalidate the binding's internal cast.

jabgui/src/test/java/org/jabref/gui/util/HoverSelectingAutoCompletionBindingTest.java

Documentation (1) +1 / -0
CHANGELOG.mdDocument corrected jump-to-field hint behavior +1/-0

Document corrected jump-to-field hint behavior

• Adds a user-facing changelog entry explaining that the creation hint no longer remains visible when an existing field is suggested.

CHANGELOG.md

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (2) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Closed dialogs retain active callbacks 📘 Rule violation ☼ Reliability
Description
dispose() removes three local listeners but neither calls super.dispose() nor invalidates
callbacks queued by JumpToFieldDialog. When the dialog closes or the binding is explicitly
disposed, inherited completion handling and pending JavaFX work can still act on its discarded
controls.
Code

jabgui/src/main/java/org/jabref/gui/util/HoverSelectingAutoCompletionBinding.java[R99-102]

+    public void dispose() {
+        textField.textProperty().removeListener(textChangeListener);
+        textField.focusedProperty().removeListener(focusChangedListener);
+        suggestionList.getSelectionModel().selectedItemProperty().removeListener(suggestionSelectionListener);
Evidence
Compliance rule 41 requires every listener registration to have deterministic cleanup and queued
work to become inactive after disposal. The new binding's cleanup only removes its three local
listeners, while the dialog registers additional listeners and schedules a callback that can update
highlightedSuggestion; the dialog's owner discards the instance on hide without invoking this
cleanup.

jabgui/src/main/java/org/jabref/gui/util/HoverSelectingAutoCompletionBinding.java[98-103]
jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[97-120]
jabgui/src/main/java/org/jabref/gui/entryeditor/EntryEditor.java[301-305]
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 new completion binding and dialog register listeners and queued callbacks without complete deterministic lifecycle cleanup. The binding's `dispose()` also omits superclass cleanup.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/util/HoverSelectingAutoCompletionBinding.java[98-103]
- jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[97-120]
## Recommended Fix
Call `super.dispose()` from the binding's `dispose()` method. On dialog closure, dispose the binding, unregister the dialog's added listeners, increment or invalidate the callback generation, and ensure every queued callback checks disposed state before changing controls.

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


2. Hint regressions go undetected 📘 Rule violation ☼ Reliability
Description
newFieldHint.visibleProperty() now computes from fieldToUse(), but the only added test asserts
that the popup skin node is a ListView. Highlighting an existing field, dismissing the popup, and
confirming a custom value therefore have no assertions covering the changed hint and selection
paths.
Code

jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[R75-77]

+        newFieldHint.managedProperty().bind(newFieldHint.visibleProperty());
+        newFieldHint.visibleProperty().bind(Bindings.createBooleanBinding(
+                () -> viewModel.isNewField(fieldToUse()), highlightedSuggestion, searchField.textProperty()));
Evidence
Compliance rule 16 requires reasonably testable behavior changes to receive corresponding coverage.
The production binding changes the hint's decision input, whereas the sole new test only verifies
the runtime type of the popup skin node and never observes hint visibility or confirmation behavior.

AGENTS.md: Update Tests for Model or Logic Changes: AGENTS.md: Update Tests for Model or Logic Changes: AGENTS.md: Update Tests for Model or Logic Changes: AGENTS.md: Update Tests for Model or Logic Changes
jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[75-77]
jabgui/src/test/java/org/jabref/gui/util/HoverSelectingAutoCompletionBindingTest.java[38-43]

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 PR changes how the dialog derives the selected field and controls the creation hint, but its new test covers only the ControlsFX skin assumption rather than this behavior.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[75-77]
- jabgui/src/test/java/org/jabref/gui/util/HoverSelectingAutoCompletionBindingTest.java[38-43]
## Recommended Fix
Add JavaFX tests that assert the hint is hidden when an existing suggestion is highlighted, shown for a custom suggestion, and recalculated from typed text after the popup is dismissed. Also verify confirmation selects the same field represented by the hint state.

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


3. Clicking OK can create the wrong field ✓ Resolved 🐞 Bug ≡ Correctness
Description
trackHighlightedSuggestion defers clearing highlightedSuggestion after the popup closes, but
confirming is only set when the OK button fires on mouse release. If the queued clear executes
after focus loss on mouse press but before release, fieldToUse() falls back to the typed prefix
instead of the highlighted existing field.
Code

jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[R107-110]

+            Platform.runLater(() -> {
+                if (!confirming && generationAtClose == popupGeneration && !autoCompletion.popupShowingProperty().get()) {
+                    highlightedSuggestion.set(null);
+                }
Evidence
The binding hides the popup immediately when the text field loses focus, and the popup-close
listener queues highlight removal. The OK result converter sets confirming only when the button
later fires; if removal occurs first, both fieldToUse() and the deferred jump use the unchanged
search text rather than the previously highlighted suggestion.

jabgui/src/main/java/org/jabref/gui/util/HoverSelectingAutoCompletionBinding.java[54-57]
jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[101-110]
jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[50-55]
jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[123-125]
jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[171-176]

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

## Issue description
Clicking the dialog's OK button while an existing autocomplete suggestion is highlighted can clear that highlight between mouse press and mouse release. Confirmation then uses the raw typed prefix and may select or create a different field.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[50-55]
- jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[101-110]
- jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[123-125]
## Recommended Fix
Capture or preserve the effective field before an OK-button mouse activation can close the popup, and have confirmation consume that captured value. Continue clearing stale highlights for ordinary popup dismissal such as Escape or focus changes not leading to confirmation, and add a JavaFX regression test covering highlighting an existing field followed by clicking OK.

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



Remediation recommended

4. Typing discards the chosen dialog size ✓ Resolved 🐞 Bug ≡ Correctness
Description
scheduleDialogResize calls Stage.sizeToScene() whenever the hint visibility changes, even after
the user has manually resized this resizable dialog. Typing between existing and new field names
repeatedly triggers the listener, restoring the preferred dimensions and discarding the dimensions
the user chose.
Code

jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[R163-165]

+                    .ifPresent(window -> {
+                        if (window instanceof Stage stage) {
+                            stage.sizeToScene();
Evidence
BaseDialog explicitly makes its windows resizable, while the new visibility listener invokes a
method that resets the stage to scene-preferred dimensions on every transition. Existing base-dialog
fitting is limited to the initial window-shown event rather than repeated during interaction.

jabgui/src/main/java/org/jabref/gui/util/BaseDialog.java[39-42]
jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[75-79]
jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[153-168]
jabgui/src/main/java/org/jabref/gui/util/BaseDialog.java[102-129]

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

## Issue description
Every new-field hint visibility transition refits the entire stage to its preferred scene size. This overwrites manual resizing while the dialog remains open.
## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[75-79]
- jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[153-168]
## Recommended Fix
Avoid calling `sizeToScene()` after every hint transition. Preserve the current width and user-added height while adjusting only for the hint's vertical space, or reserve stable layout space for the hint so no stage resize is required.

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


Grey Divider

Tip of the day
💡 Did you know, you can start a comment with 'qodo' or '@qodo' to chat about any finding

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment on lines +75 to +77
newFieldHint.managedProperty().bind(newFieldHint.visibleProperty());
newFieldHint.visibleProperty().bind(Bindings.createBooleanBinding(
() -> viewModel.isNewField(fieldToUse()), highlightedSuggestion, searchField.textProperty()));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

2. Hint regressions go undetected 📘 Rule violation ☼ Reliability

newFieldHint.visibleProperty() now computes from fieldToUse(), but the only added test asserts
that the popup skin node is a ListView. Highlighting an existing field, dismissing the popup, and
confirming a custom value therefore have no assertions covering the changed hint and selection
paths.
Agent Prompt
## Issue description
The PR changes how the dialog derives the selected field and controls the creation hint, but its new test covers only the ControlsFX skin assumption rather than this behavior.

## Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java[75-77]
- jabgui/src/test/java/org/jabref/gui/util/HoverSelectingAutoCompletionBindingTest.java[38-43]

## Recommended Fix
Add JavaFX tests that assert the hint is hidden when an existing suggestion is highlighted, shown for a custom suggestion, and recalculated from typed text after the popup is dismissed. Also verify confirmation selects the same field represented by the hint state.

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

Comment thread jabgui/src/main/java/org/jabref/gui/entryeditor/JumpToFieldDialog.java Outdated
@github-actions github-actions Bot removed the status: changes-required Pull requests that are not yet complete label Sep 12, 2026
@jabref-machine jabref-machine added the status: changes-required Pull requests that are not yet complete label Sep 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Jump to field dialog hint overlaps suggestion list, ignores hovered suggestion, and pushes buttons out of view

2 participants