Skip to content

Commit ecd271a

Browse files
authored
Fix Tagsfield in Keyword editor (#13858)
* Add failing test * Fix StringConverter * CHANGELOG.md * Cleanup
1 parent a5a2fb3 commit ecd271a

File tree

6 files changed

+37
-16
lines changed

6 files changed

+37
-16
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ Note that this project **does not** adhere to [Semantic Versioning](https://semv
131131
- We fixed an issue where theme or font size are not respected for all dialogs [#13558](https://github.com/JabRef/jabref/issues/13558)
132132
- We removed unnecessary spacing and margin in the AutomaticFieldEditor. [#13792](https://github.com/JabRef/jabref/pull/13792)
133133
- We fixed an issue where global search auto-completion only worked after switching tabs. [#11428](https://github.com/JabRef/jabref/issues/11428)
134+
- We fixed an issue where hierarchical keywords would only show the parent keyword in the entry editor. [#11390](https://github.com/JabRef/jabref/issues/11390)
134135

135136
### Removed
136137

jabgui/src/main/java/org/jabref/gui/fieldeditors/KeywordsEditor.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,17 +109,17 @@ public KeywordsEditor(Field field,
109109
keywordTagsField.setTagViewFactory(this::createTag);
110110

111111
keywordTagsField.setSuggestionProvider(request -> viewModel.getSuggestions(request.getUserText()));
112-
keywordTagsField.setConverter(viewModel.getStringConverter());
112+
keywordTagsField.setConverter(KeywordsEditorViewModel.getStringConverter());
113113
keywordTagsField.setMatcher((keyword, searchText) -> keyword.get().toLowerCase().startsWith(searchText.toLowerCase()));
114114
keywordTagsField.setComparator(Comparator.comparing(Keyword::get));
115115

116-
keywordTagsField.setNewItemProducer(searchText -> viewModel.getStringConverter().fromString(searchText));
116+
keywordTagsField.setNewItemProducer(searchText -> KeywordsEditorViewModel.getStringConverter().fromString(searchText));
117117

118118
keywordTagsField.setShowSearchIcon(false);
119-
keywordTagsField.setOnMouseClicked(event -> keywordTagsField.getEditor().requestFocus());
119+
keywordTagsField.setOnMouseClicked(_ -> keywordTagsField.getEditor().requestFocus());
120120
keywordTagsField.getEditor().getStyleClass().clear();
121121
keywordTagsField.getEditor().getStyleClass().add("tags-field-editor");
122-
keywordTagsField.getEditor().focusedProperty().addListener((observable, oldValue, newValue) -> keywordTagsField.pseudoClassStateChanged(FOCUSED, newValue));
122+
keywordTagsField.getEditor().focusedProperty().addListener((_, _, newValue) -> keywordTagsField.pseudoClassStateChanged(FOCUSED, newValue));
123123

124124
String keywordSeparator = String.valueOf(viewModel.getKeywordSeparator());
125125
keywordTagsField.getEditor().setOnKeyReleased(event -> {
@@ -129,7 +129,7 @@ public KeywordsEditor(Field field,
129129
}
130130
});
131131

132-
this.viewModel.keywordListProperty().addListener((observable, oldValue, newValue) -> {
132+
this.viewModel.keywordListProperty().addListener((_, _, _) -> {
133133
if (keywordTagsField.getTags().size() < 2) {
134134
isSortedTagsField = false;
135135
} else if ((Comparators.isInOrder(keywordTagsField.getTags(), Comparator.comparing(Keyword::get))) || isSortedTagsField) {
@@ -159,7 +159,7 @@ private Node createTag(Keyword keyword) {
159159
Label tagLabel = new Label();
160160
tagLabel.setText(keywordTagsField.getConverter().toString(keyword));
161161
tagLabel.setGraphic(IconTheme.JabRefIcons.REMOVE_TAGS.getGraphicNode());
162-
tagLabel.getGraphic().setOnMouseClicked(event -> keywordTagsField.removeTags(keyword));
162+
tagLabel.getGraphic().setOnMouseClicked(_ -> keywordTagsField.removeTags(keyword));
163163
tagLabel.setContentDisplay(ContentDisplay.RIGHT);
164164
ContextMenu contextMenu = new ContextMenu();
165165
ActionFactory factory = new ActionFactory();
@@ -198,8 +198,8 @@ private Node createTag(Keyword keyword) {
198198
draggedKeyword = Optional.of(keyword);
199199
event.consume();
200200
});
201-
tagLabel.setOnDragEntered(event -> tagLabel.setStyle("-fx-background-color: lightgrey;"));
202-
tagLabel.setOnDragExited(event -> tagLabel.setStyle(""));
201+
tagLabel.setOnDragEntered(_ -> tagLabel.setStyle("-fx-background-color: lightgrey;"));
202+
tagLabel.setOnDragExited(_ -> tagLabel.setStyle(""));
203203
tagLabel.setOnDragDropped(event -> {
204204
Dragboard db = event.getDragboard();
205205
if (db.hasString() && draggedKeyword.isPresent()) {

jabgui/src/main/java/org/jabref/gui/fieldeditors/KeywordsEditorViewModel.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,20 +60,20 @@ public ListProperty<Keyword> keywordListProperty() {
6060
return keywordListProperty;
6161
}
6262

63-
public StringConverter<Keyword> getStringConverter() {
63+
static StringConverter<Keyword> getStringConverter() {
6464
return new StringConverter<>() {
6565
@Override
6666
public String toString(Keyword keyword) {
6767
if (keyword == null) {
6868
LOGGER.debug("Keyword is null");
6969
return "";
7070
}
71-
return keyword.get();
71+
return keyword.toString();
7272
}
7373

7474
@Override
7575
public Keyword fromString(String keywordString) {
76-
return new Keyword(keywordString);
76+
return Keyword.ofHierarchical(keywordString);
7777
}
7878
};
7979
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.jabref.gui.fieldeditors;
2+
3+
import org.jabref.model.entry.Keyword;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
import static org.junit.jupiter.api.Assertions.assertEquals;
8+
9+
class KeywordsEditorViewModelTest {
10+
@Test
11+
void stringConverterWithHierarchicalKeywords() {
12+
String hierarchichalString = "parent > node > child";
13+
Keyword keyword = Keyword.ofHierarchical(hierarchichalString);
14+
15+
assertEquals(hierarchichalString, KeywordsEditorViewModel.getStringConverter().toString(keyword));
16+
}
17+
}

jablib/src/main/java/org/jabref/model/entry/Keyword.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@ public Keyword(String keyword) {
2121
this.keyword = Objects.requireNonNull(keyword).trim();
2222
}
2323

24-
/**
25-
* Connects all the given keywords into one chain and returns its root,
26-
* e.g. "A", "B", "C" is transformed into "A > B > C".
27-
*/
24+
/// Connects all the given keywords into one chain and returns its root,
25+
/// e.g. "A", "B", "C" is transformed into "A > B > C".
2826
public static Keyword of(String... keywords) {
2927
if (keywords.length == 0) {
3028
return new Keyword("");
@@ -37,6 +35,11 @@ public static Keyword of(String... keywords) {
3735
return root;
3836
}
3937

38+
/// Converts a raw String to a single Keyword
39+
public static Keyword ofHierarchical(String rawString) {
40+
return Keyword.of(rawString.split(Keyword.DEFAULT_HIERARCHICAL_DELIMITER.toString()));
41+
}
42+
4043
@Override
4144
public boolean equals(Object o) {
4245
if (this == o) {

jablib/src/main/java/org/jabref/model/entry/KeywordList.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public static KeywordList parse(String keywordString, Character delimiter, Chara
5656
StringTokenizer tok = new StringTokenizer(keywordString, delimiter.toString());
5757
while (tok.hasMoreTokens()) {
5858
String chain = tok.nextToken();
59-
Keyword chainRoot = Keyword.of(chain.split(hierarchicalDelimiter.toString()));
59+
Keyword chainRoot = Keyword.ofHierarchical(chain);
6060
keywordList.add(chainRoot);
6161
}
6262
return keywordList;

0 commit comments

Comments
 (0)