Skip to content

Fix #12351: Improved tooltip responsiveness and removed empty space in entry preview#14973

Merged
calixtus merged 15 commits into
JabRef:mainfrom
lithincg:fix-tooltip-sizing
Feb 2, 2026
Merged

Fix #12351: Improved tooltip responsiveness and removed empty space in entry preview#14973
calixtus merged 15 commits into
JabRef:mainfrom
lithincg:fix-tooltip-sizing

Conversation

@lithincg

@lithincg lithincg commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

User description

Closes

Closes #12351

Description

This PR improves the entry preview tooltip in the main table by dynamically adjusting its height to fit the citation content.
I refactored the layout to align with JavaFX's encapsulation principles: the resizing logic is now owned by PreviewViewer, while the Tooltip manages the window sizing. This eliminates the "ghost" space (giant empty dark boxes) and removes redundant labels for a cleaner, more responsive UI.

Steps to test

Steps to test

  1. Open JabRef and ensure "Show preview in Entry table tooltip" is enabled in Preferences > Entry preview.
  2. Hover over an entry in the main table.
  3. Verify: The tooltip should "shrink-wrap" the citation text.
  4. Verify: There should no longer be a large empty dark area at the bottom of the tooltip.
  5. Verify: The cell's plain text should no longer be duplicated at the top of the formatted citation.

Before:
image

After:
image

Mandatory checks

  • 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 (not applicable for this UI tooltip fix)
  • I added screenshots in the PR description (if change is visible to the user)
  • I described the change in CHANGELOG.md in a way that is understandable for the average user (if change is visible to the user)
  • [/] I checked the user documentation

PR Type

Enhancement, Bug fix


Description

  • Dynamically adjusts tooltip height to fit citation content via WebView listener

  • Removes redundant field label from preview tooltip for compact display

  • Executes JavaScript to measure actual content height and resize WebView accordingly

  • Sets fixed width (600px) and calculates height based on rendered content


Diagram Walkthrough

flowchart LR
  A["MainTableTooltip"] -->|extracts WebView| B["PreviewViewer"]
  B -->|measures content| C["JavaScript getBoundingClientRect"]
  C -->|returns height| D["Dynamic WebView sizing"]
  D -->|calls sizeToScene| E["Compact tooltip display"]
Loading

File Walkthrough

Relevant files
Enhancement
MainTableTooltip.java
Implement dynamic WebView height calculation for tooltips

jabgui/src/main/java/org/jabref/gui/maintable/MainTableTooltip.java

  • Replaced VBox layout with direct WebView extraction from PreviewViewer
  • Added load state listener to dynamically calculate and set WebView
    height based on rendered content
  • Removed redundant fieldValueLabel from preview tooltip display
  • Set fixed width (600px) and dynamic height with 15px padding
    adjustment
+35/-6   
PreviewViewer.java
Expose WebEngine accessor method                                                 

jabgui/src/main/java/org/jabref/gui/preview/PreviewViewer.java

  • Added public getEngine() method to expose WebEngine from internal
    previewView
  • Enables external access to WebView engine for JavaScript execution and
    content measurement
+5/-0     
Documentation
CHANGELOG.md
Document tooltip improvement in changelog                               

CHANGELOG.md

+1/-0     

@github-actions

Copy link
Copy Markdown
Contributor

Hey @lithincg! 👋

Thank you for contributing to JabRef!

We have automated checks in place, based on which you will soon get feedback if any of them are failing. We also use Qodo for review assistance. It will update your pull request description with a review help and offer suggestions to improve the pull request.

After all automated checks pass, a maintainer will also review your contribution. Once that happens, you can go through their comments in the "Files changed" tab and act on them, or reply to the conversation if you have further inputs. You can read about the whole pull request process in our contribution guide.

Please ensure that your pull request is in line with our AI Usage Policy and make necessary disclosures.

@github-actions github-actions Bot added first contrib good first issue An issue intended for project-newcomers. Varies in difficulty. labels Jan 31, 2026
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
Unvalidated JavaScript execution

Description: JavaScript code is executed without sanitization or validation, potentially allowing
script injection if the WebView content contains malicious code that could manipulate the
DOM or execute arbitrary JavaScript through the document.getElementById('content') or
document.body.scrollHeight access.
MainTableTooltip.java [38-41]

Referred Code
Object result = webView.getEngine().executeScript(
        "var content = document.getElementById('content');" +
                "content ? content.getBoundingClientRect().height : document.body.scrollHeight;"
);
WebEngine exposure risk

Description: Exposing the WebEngine publicly allows external code to execute arbitrary JavaScript in
the WebView context, potentially enabling XSS attacks if untrusted content is loaded or if
the engine is accessed by malicious code.
PreviewViewer.java [352-354]

Referred Code
public WebEngine getEngine() {
    return previewView.getEngine();
}
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Comprehensive Audit Trails

Objective: To create a detailed and reliable record of critical system actions for security analysis
and compliance.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Missing null check: The JavaScript execution result is cast to Number without verifying the result is not
null, which could cause a NullPointerException if the script fails.

Referred Code
Object result = webView.getEngine().executeScript(
        "var content = document.getElementById('content');" +
                "content ? content.getBoundingClientRect().height : document.body.scrollHeight;"
);

if (result instanceof Number height) {
    double actualH = height.doubleValue() + 15;

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
Unvalidated JavaScript execution: JavaScript is executed on WebView content without validation of the result, which could be
exploited if the preview content contains malicious scripts.

Referred Code
Object result = webView.getEngine().executeScript(
        "var content = document.getElementById('content');" +
                "content ? content.getBoundingClientRect().height : document.body.scrollHeight;"
);

Learn more about managing compliance generic rules or creating your own custom rules

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

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

qodo-free-for-open-source-projects Bot commented Jan 31, 2026

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Add error handling for script execution

Wrap the webView.getEngine().executeScript() call in a try-catch block to handle
potential JSException and prevent the application from crashing.

jabgui/src/main/java/org/jabref/gui/maintable/MainTableTooltip.java [35-54]

 webView.getEngine().getLoadWorker().stateProperty().addListener((obs, oldState, newState) -> {
     if (newState == Worker.State.SUCCEEDED) {
         Platform.runLater(() -> {
-            Object result = webView.getEngine().executeScript(
-                    "var content = document.getElementById('content');" +
-                            "content ? content.getBoundingClientRect().height : document.body.scrollHeight;"
-            );
+            try {
+                Object result = webView.getEngine().executeScript(
+                        "var content = document.getElementById('content');" +
+                                "content ? content.getBoundingClientRect().height : document.body.scrollHeight;"
+                );
 
-            if (result instanceof Number height) {
-                double actualH = height.doubleValue() + 15;
+                if (result instanceof Number height) {
+                    double actualH = height.doubleValue() + 15;
 
-                webView.setPrefHeight(actualH);
-                webView.setMaxHeight(actualH);
-                webView.setMinHeight(actualH);
+                    webView.setPrefHeight(actualH);
+                    webView.setMaxHeight(actualH);
+                    webView.setMinHeight(actualH);
 
-                sizeToScene();
+                    sizeToScene();
+                }
+            } catch (netscape.javascript.JSException e) {
+                // Log the exception or handle it gracefully.
+                // For example, you could log it to avoid crashing the application.
+                // LOGGER.warn("JavaScript execution failed in tooltip", e);
             }
         });
     }
 });
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies that an unhandled JSException on the JavaFX application thread could crash the UI. Adding a try-catch block is a crucial improvement for the robustness and stability of the application.

Medium
Learned
best practice
Add Javadoc for public method

Add Javadoc documentation to the new public getEngine() method to explain its
purpose and return value, following the existing documentation pattern in the
class.

jabgui/src/main/java/org/jabref/gui/preview/PreviewViewer.java [352-354]

+/// Returns the WebEngine of the preview view for external access.
+///
+/// @return the WebEngine instance used by the preview view
 public WebEngine getEngine() {
     return previewView.getEngine();
 }
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why:
Relevant best practice - Add proper Javadoc documentation for public methods to explain their purpose, parameters, return values, and any side effects, maintaining code clarity and professionalism.

Low
  • Update

@github-actions github-actions Bot added the status: changes-required Pull requests that are not yet complete label Jan 31, 2026
@github-actions github-actions Bot removed the status: changes-required Pull requests that are not yet complete label Jan 31, 2026
Comment thread jabgui/src/main/java/org/jabref/gui/maintable/MainTableTooltip.java Outdated
@github-actions github-actions Bot added the status: changes-required Pull requests that are not yet complete label Feb 1, 2026
@github-actions

github-actions Bot commented Feb 1, 2026

Copy link
Copy Markdown
Contributor

Your pull request conflicts with the target branch.

Please merge with your code. For a step-by-step guide to resolve merge conflicts, see https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line.

@github-actions github-actions Bot removed the status: changes-required Pull requests that are not yet complete label Feb 1, 2026
@github-actions github-actions Bot added the status: changes-required Pull requests that are not yet complete label Feb 1, 2026
@lithincg lithincg force-pushed the fix-tooltip-sizing branch 3 times, most recently from ee2dbe8 to 34155e1 Compare February 1, 2026 05:50
@github-actions github-actions Bot removed the status: changes-required Pull requests that are not yet complete label Feb 1, 2026
@lithincg

lithincg commented Feb 1, 2026

Copy link
Copy Markdown
Contributor Author

I apologize for the commit clutter and force pushes earlier. This is my first PR, and got a bit caught up in merge conflicts and formatting issues. I have made the changes as requested and fixed the CHANGELOG.md formatting as well. The tests seem to be passing now(except the "Binaries / comment-on-issue-and-pr (pull_request)" . I am not sure if it is related to my code tho).

@Siedlerchr

Copy link
Copy Markdown
Member

No worries, it's okay.

@Siedlerchr Siedlerchr added the status: ready-for-review Pull Requests that are ready to be reviewed by the maintainers label Feb 1, 2026
Siedlerchr
Siedlerchr previously approved these changes Feb 1, 2026
@Siedlerchr

Copy link
Copy Markdown
Member

I found extreme case where it's cut off, but all other cases looked good

paste the DOI to get the entry:
10.48550/arXiv.2601.10795

grafik

@koppor koppor removed the request for review from calixtus February 2, 2026 10:41
@koppor koppor removed the status: awaiting-second-review For non-trivial changes label Feb 2, 2026
@koppor koppor added this pull request to the merge queue Feb 2, 2026
github-merge-queue Bot pushed a commit that referenced this pull request Feb 2, 2026
…n entry preview (#14973)

* Fix #12351: Shrink entry preview tooltip area to fit content

* Update changelog

* Fix changelog spacing and java formatting

* Move tooltip resizing logic into PreviewViewer

* fix: increase tooltip width to 750px to handle extreme cases

* Use _

---------

Co-authored-by: Oliver Kopp <kopp.dev@gmail.com>
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Feb 2, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Feb 2, 2026
Comment thread jabgui/src/main/java/org/jabref/gui/preview/PreviewViewer.java Outdated

@calixtus calixtus left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Everything looks good to me except one magic number. Then good to merge. Thanks.

@github-actions github-actions Bot added the status: changes-required Pull requests that are not yet complete label Feb 2, 2026
@koppor koppor added status: close-to-finish and removed status: to-be-merged PRs which are accepted and should go into the merge-queue. labels Feb 2, 2026
@github-actions github-actions Bot removed the status: changes-required Pull requests that are not yet complete label Feb 2, 2026
Comment thread jabgui/src/main/java/org/jabref/gui/preview/PreviewViewer.java Outdated
@calixtus calixtus enabled auto-merge February 2, 2026 13:44
@lithincg

lithincg commented Feb 2, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for the reviews and helpful suggestions in this PR!

@calixtus calixtus added this pull request to the merge queue Feb 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 Feb 2, 2026
Merged via the queue into JabRef:main with commit e472ce5 Feb 2, 2026
53 of 54 checks passed
@koppor

koppor commented Feb 8, 2026

Copy link
Copy Markdown
Member

Global search: still much white space

grafik

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

first contrib good first issue An issue intended for project-newcomers. Varies in difficulty. Review effort 2/5 status: close-to-finish 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.

Area of preview on hover should be shrink to the size of the text displayed

4 participants