Skip to content

Fix crash when scrolling through cited by in Citation relations #12877

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 18, 2025
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
- We fixed an issue where JabRef interface would not properly refresh after a group removal. [#11487](https://github.com/JabRef/jabref/issues/11487)
- We fixed an issue where valid DOI could not be imported if it had special characters like `<` or `>`. [#12434](https://github.com/JabRef/jabref/issues/12434)
- We fixed an issue where the tooltip only displayed the first linked file when hovering. [#12470](https://github.com/JabRef/jabref/issues/12470)
- We fixed an issue where JabRef would crash when trying to display an entry in the Citation Relations tab that had right to left text. [#12410](https://github.com/JabRef/jabref/issues/12410)
- We fixed an issue where some texts in the "Citation Information" tab and the "Preferences" dialog could not be translated. [#12883](https://github.com/JabRef/jabref/pull/12883)

### Removed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
Expand Down Expand Up @@ -32,24 +33,26 @@ public class BibEntryView {
public static Node getEntryNode(BibEntry entry) {
Node entryType = getIcon(entry.getType()).getGraphicNode();
entryType.getStyleClass().add("type");
Label authors = new Label(entry.getFieldOrAliasLatexFree(StandardField.AUTHOR).orElse(""));
String authorsText = entry.getFieldOrAliasLatexFree(StandardField.AUTHOR).orElse("");
Node authors = createLabel(authorsText);
authors.getStyleClass().add("authors");
authors.setWrapText(true);
Label title = new Label(entry.getFieldOrAliasLatexFree(StandardField.TITLE).orElse(""));
String titleText = entry.getFieldOrAliasLatexFree(StandardField.TITLE).orElse("");
Node title = createLabel(titleText);
title.getStyleClass().add("title");
title.setWrapText(true);
Label year = new Label(entry.getFieldOrAliasLatexFree(StandardField.YEAR).orElse(""));
year.getStyleClass().add("year");
Label journal = new Label(entry.getFieldOrAliasLatexFree(StandardField.JOURNAL).orElse(""));
String journalText = entry.getFieldOrAliasLatexFree(StandardField.JOURNAL).orElse("");
Node journal = createLabel(journalText);
journal.getStyleClass().add("journal");

VBox entryContainer = new VBox(
new HBox(10, entryType, title),
new HBox(5, year, journal),
authors
);

entry.getFieldOrAliasLatexFree(StandardField.ABSTRACT).ifPresent(summaryText -> {
TextFlowLimited summary = new TextFlowLimited(new Text(summaryText));
Node summary = createSummary(summaryText);
summary.getStyleClass().add("summary");
entryContainer.getChildren().add(summary);
});
Expand All @@ -74,4 +77,64 @@ private static IconTheme.JabRefIcons getIcon(EntryType type) {
}
return IconTheme.JabRefIcons.ARTICLE;
}

/**
* Checks if text contains right-to-left characters
*
* @param text Text to check
* @return true if text contains RTL characters
*/
private static boolean isRTL(String text) {
for (char c : text.toCharArray()) {
if (Character.getDirectionality(c) == Character.DIRECTIONALITY_RIGHT_TO_LEFT ||
Character.getDirectionality(c) == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC) {
return true;
}
}
return false;
}

/**
* Creates a text node for the summary with horizontal scrolling for RTL text,
* avoiding JavaFX bug related to RTL text wrapping
*
* @param text The summary text content
* @return Node with either:
* - ScrollPane (for RTL text)
* - TextFlowLimited (for LTR text)
*/
private static Node createSummary(String text) {
if (isRTL(text)) {
Text textNode = new Text(text);
ScrollPane scrollPane = new ScrollPane(textNode);
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
scrollPane.setFitToHeight(true);
return scrollPane;
} else {
return new TextFlowLimited(new Text(text));
}
}

/**
* Creates a label with horizontal scrolling for RTL text,
* avoiding JavaFX bug related to RTL text wrapping
*
* @param text The label text content
* @return Node with either:
* - ScrollPane (for RTL text)
* - Wrapped Label (for LTR text)
*/
private static Node createLabel(String text) {
if (isRTL(text)) {
Label label = new Label(text);
ScrollPane scrollPane = new ScrollPane(label);
scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
scrollPane.setFitToHeight(true);
return scrollPane;
} else {
Label label = new Label(text);
label.setWrapText(true);
return label;
}
}
}
Loading