-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Used late initialization for context menus #3340
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.function.Supplier; | ||
|
||
import javax.swing.AbstractAction; | ||
import javax.swing.Action; | ||
|
@@ -14,42 +15,73 @@ | |
import javafx.scene.control.Tooltip; | ||
|
||
import org.jabref.gui.actions.CopyDoiUrlAction; | ||
import org.jabref.gui.fieldeditors.EditorTextArea; | ||
import org.jabref.logic.formatter.bibtexfields.NormalizeNamesFormatter; | ||
import org.jabref.logic.l10n.Localization; | ||
|
||
/** | ||
* Provides context menus for the text fields of the entry editor. Note that we use {@link Supplier} to prevent an early | ||
* instantiation of the menus. Therefore, they are attached to each text field but instantiation happens on the first | ||
* right-click of the user in that field. The late instantiation is done by {@link | ||
* EditorTextArea#addToContextMenu(java.util.function.Supplier)}. | ||
*/ | ||
public class EditorMenus { | ||
|
||
public static List<MenuItem> getDefaultMenu(TextArea textArea) { | ||
List<MenuItem> menuItems = new ArrayList<>(5); | ||
menuItems.add(new CaseChangeMenu(textArea.textProperty())); | ||
menuItems.add(new ConversionMenu(textArea.textProperty())); | ||
menuItems.add(new SeparatorMenuItem()); | ||
menuItems.add(new ProtectedTermsMenu(textArea)); | ||
menuItems.add(new SeparatorMenuItem()); | ||
return menuItems; | ||
/** | ||
* The default menu that contains functions for changing the case of text and doing several conversions. | ||
* | ||
* @param textArea text-area that this menu will be connected to | ||
* @return default context menu available for most text fields | ||
*/ | ||
public static Supplier<List<MenuItem>> getDefaultMenu(TextArea textArea) { | ||
return () -> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what is more readable: Hiding the supplier interface here like you did or instead writing something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I am in favor of the second solution, i.e. putting the supplier into My perception might be wrong, though. Please correct me if this is the case. |
||
List<MenuItem> menuItems = new ArrayList<>(5); | ||
menuItems.add(new CaseChangeMenu(textArea.textProperty())); | ||
menuItems.add(new ConversionMenu(textArea.textProperty())); | ||
menuItems.add(new SeparatorMenuItem()); | ||
menuItems.add(new ProtectedTermsMenu(textArea)); | ||
menuItems.add(new SeparatorMenuItem()); | ||
return menuItems; | ||
}; | ||
} | ||
|
||
public static List<MenuItem> getNameMenu(TextArea textArea) { | ||
CustomMenuItem normalizeNames = new CustomMenuItem(new Label(Localization.lang("Normalize to BibTeX name format"))); | ||
normalizeNames.setOnAction(event -> textArea.setText(new NormalizeNamesFormatter().format(textArea.getText()))); | ||
Tooltip toolTip = new Tooltip(Localization.lang("If possible, normalize this list of names to conform to standard BibTeX name formatting")); | ||
Tooltip.install(normalizeNames.getContent(),toolTip); | ||
/** | ||
* The default context menu with a specific menu for normalizing person names regarding to BibTex rules. | ||
* | ||
* @param textArea text-area that this menu will be connected to | ||
* @return menu containing items of the default menu and an item for normalizing person names | ||
*/ | ||
public static Supplier<List<MenuItem>> getNameMenu(TextArea textArea) { | ||
return () -> { | ||
CustomMenuItem normalizeNames = new CustomMenuItem(new Label(Localization.lang("Normalize to BibTeX name format"))); | ||
normalizeNames.setOnAction(event -> textArea.setText(new NormalizeNamesFormatter().format(textArea.getText()))); | ||
Tooltip toolTip = new Tooltip(Localization.lang("If possible, normalize this list of names to conform to standard BibTeX name formatting")); | ||
Tooltip.install(normalizeNames.getContent(), toolTip); | ||
|
||
List<MenuItem> menuItems = new ArrayList<>(6); | ||
menuItems.add(normalizeNames); | ||
menuItems.addAll(getDefaultMenu(textArea)); | ||
|
||
return menuItems; | ||
List<MenuItem> menuItems = new ArrayList<>(6); | ||
menuItems.add(normalizeNames); | ||
menuItems.addAll(getDefaultMenu(textArea).get()); | ||
return menuItems; | ||
}; | ||
} | ||
|
||
public static List<MenuItem> getDOIMenu(TextArea textArea) { | ||
AbstractAction copyDoiUrlAction = new CopyDoiUrlAction(textArea); | ||
MenuItem copyDoiUrlMenuItem = new MenuItem((String) copyDoiUrlAction.getValue(Action.NAME)); | ||
copyDoiUrlMenuItem.setOnAction(event -> copyDoiUrlAction.actionPerformed(null)); | ||
/** | ||
* The default context menu with a specific menu copying a DOI URL. | ||
* | ||
* @param textArea text-area that this menu will be connected to | ||
* @return menu containing items of the default menu and an item for copying a DOI URL | ||
*/ | ||
public static Supplier<List<MenuItem>> getDOIMenu(TextArea textArea) { | ||
return () -> { | ||
AbstractAction copyDoiUrlAction = new CopyDoiUrlAction(textArea); | ||
MenuItem copyDoiUrlMenuItem = new MenuItem((String) copyDoiUrlAction.getValue(Action.NAME)); | ||
copyDoiUrlMenuItem.setOnAction(event -> copyDoiUrlAction.actionPerformed(null)); | ||
|
||
List<MenuItem> menuItems = new ArrayList<>(); | ||
menuItems.add(copyDoiUrlMenuItem); | ||
menuItems.add(new SeparatorMenuItem()); | ||
return menuItems; | ||
List<MenuItem> menuItems = new ArrayList<>(); | ||
menuItems.add(copyDoiUrlMenuItem); | ||
menuItems.add(new SeparatorMenuItem()); | ||
menuItems.addAll(getDefaultMenu(textArea).get()); | ||
return menuItems; | ||
}; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand everything correctly, we could build the supplier right here and still accept a
List<MenuItem>
as method parameter. That would keep the changes very localized.More discussion see below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, then I misunderstood the whole thing. Every text-field editor needs to attach its own context menu. Als long as I have wrapped it in a supplier, the code is not instantiated. So how is for instance
IdentifierEditor
supposed to attach a non-instantiated context menu?Assume we don't do the wrapping inside
EditorMenus
, then the menu would be instantiated exactly there. Except when I put theSupplier
wrapper at this place. But then we have the suppliers scattered over even more classes. What do I miss?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, Jörg, the supplier has to be built outside of this method since otherwise the context menu items are already created. With the help of a supplier, we are able to delay the creation until the user opens the context menu (since only then the
get
method is called).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, then I was wrong. Thanks for clarifying! In that case, please disregard my comment and keep the solution.