diff --git a/src/main/java/org/jabref/Globals.java b/src/main/java/org/jabref/Globals.java index 0e0b4457f4d..60a1d626acf 100644 --- a/src/main/java/org/jabref/Globals.java +++ b/src/main/java/org/jabref/Globals.java @@ -7,7 +7,6 @@ import javafx.stage.Screen; import org.jabref.gui.ClipBoardManager; -import org.jabref.gui.GlobalFocusListener; import org.jabref.gui.StateManager; import org.jabref.gui.keyboard.KeyBindingRepository; import org.jabref.gui.util.DefaultFileUpdateMonitor; @@ -60,8 +59,6 @@ public class Globals { public static ExporterFactory exportFactory; // Key binding preferences private static KeyBindingRepository keyBindingRepository; - // Background tasks - private static GlobalFocusListener focusListener; private static DefaultFileUpdateMonitor fileUpdateMonitor; private static ThemeLoader themeLoader; private static TelemetryClient telemetryClient; @@ -79,8 +76,6 @@ public static synchronized KeyBindingRepository getKeyPrefs() { // Background tasks public static void startBackgroundTasks() { - Globals.focusListener = new GlobalFocusListener(); - Globals.fileUpdateMonitor = new DefaultFileUpdateMonitor(); JabRefExecutorService.INSTANCE.executeInterruptableTask(Globals.fileUpdateMonitor, "FileUpdateMonitor"); @@ -117,10 +112,6 @@ private static void startTelemetryClient() { telemetryClient.trackSessionState(SessionState.Start); } - public static GlobalFocusListener getFocusListener() { - return focusListener; - } - public static FileUpdateMonitor getFileUpdateMonitor() { return fileUpdateMonitor; } diff --git a/src/main/java/org/jabref/gui/BasePanel.java b/src/main/java/org/jabref/gui/BasePanel.java index efe88110716..66f4b7647e5 100644 --- a/src/main/java/org/jabref/gui/BasePanel.java +++ b/src/main/java/org/jabref/gui/BasePanel.java @@ -305,11 +305,11 @@ private void setupActions() { actions.put(Actions.SAVE_SELECTED_AS_PLAIN, new SaveSelectedAction(SavePreferences.DatabaseSaveType.PLAIN_BIBTEX)); // The action for copying selected entries. - actions.put(Actions.COPY, mainTable::copy); + actions.put(Actions.COPY, this::copy); actions.put(Actions.PRINT_PREVIEW, new PrintPreviewAction()); - actions.put(Actions.CUT, mainTable::cut); + actions.put(Actions.CUT, this::cut); actions.put(Actions.DELETE, () -> delete(false)); @@ -319,7 +319,7 @@ private void setupActions() { // This allows you to (a) paste entire bibtex entries from a text editor, web browser, etc // (b) copy and paste entries between multiple instances of JabRef (since // only the text representation seems to get as far as the X clipboard, at least on my system) - actions.put(Actions.PASTE, mainTable::paste); + actions.put(Actions.PASTE, this::paste); actions.put(Actions.SELECT_ALL, mainTable.getSelectionModel()::selectAll); @@ -1379,6 +1379,18 @@ public Path getTempFile() { return changeMonitor.map(DatabaseChangeMonitor::getTempFile).orElse(null); } + public void copy() { + mainTable.copy(); + } + + public void paste() { + mainTable.paste(); + } + + public void cut() { + mainTable.cut(); + } + private static class SearchAndOpenFile { private final BibEntry entry; diff --git a/src/main/java/org/jabref/gui/GlobalFocusListener.java b/src/main/java/org/jabref/gui/GlobalFocusListener.java deleted file mode 100644 index 865de194b33..00000000000 --- a/src/main/java/org/jabref/gui/GlobalFocusListener.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.jabref.gui; - -import java.awt.Component; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; - -import javax.swing.JComponent; - -public class GlobalFocusListener implements FocusListener { - private Component focused; - - @Override - public void focusGained(FocusEvent e) { - if (!e.isTemporary()) { - focused = (Component) e.getSource(); - } - } - - @Override - public void focusLost(FocusEvent e) { - // Do nothing - } - - public JComponent getFocused() { - return (JComponent) focused; - } - - public void setFocused(Component c) { - focused = c; - } -} diff --git a/src/main/java/org/jabref/gui/JabRefFrame.java b/src/main/java/org/jabref/gui/JabRefFrame.java index 7e8b983de25..6c79182fc5b 100644 --- a/src/main/java/org/jabref/gui/JabRefFrame.java +++ b/src/main/java/org/jabref/gui/JabRefFrame.java @@ -2,7 +2,6 @@ import java.awt.Component; import java.awt.Window; -import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; import java.nio.file.Path; @@ -18,7 +17,6 @@ import java.util.stream.Collectors; import javax.swing.Action; -import javax.swing.JComponent; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; @@ -39,6 +37,7 @@ import javafx.scene.control.SplitPane; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; +import javafx.scene.control.TextInputControl; import javafx.scene.control.ToolBar; import javafx.scene.control.Tooltip; import javafx.scene.input.DataFormat; @@ -284,8 +283,7 @@ private void init() { //previewToggle.setSelected(Globals.prefs.getPreviewPreferences().isPreviewPanelEnabled()); //generalFetcher.getToggleCommand().setSelected(sidePaneManager.isComponentVisible(WebSearchPane.class)); //openOfficePanel.getToggleCommand().setSelected(sidePaneManager.isComponentVisible(OpenOfficeSidePanel.class)); - // TODO: Can't notify focus listener since it is expecting a swing component - //Globals.getFocusListener().setFocused(currentBasePanel.getMainTable()); + setWindowTitle(); // Update search autocompleter with information for the correct database: currentBasePanel.updateSearchManager(); @@ -1442,10 +1440,40 @@ public EditAction(Actions command) { @Override public void execute() { - JComponent source = Globals.getFocusListener().getFocused(); - Action action = source.getActionMap().get(command); - if (action != null) { - action.actionPerformed(new ActionEvent(source, 0, command.name())); + Node focusOwner = mainStage.getScene().getFocusOwner(); + if (focusOwner != null) { + if (focusOwner instanceof TextInputControl) { + // Focus is on text field -> copy/paste/cut selected text + TextInputControl textInput = (TextInputControl) focusOwner; + switch (command) { + case COPY: + textInput.copy(); + break; + case CUT: + textInput.cut(); + break; + case PASTE: + textInput.paste(); + break; + default: + throw new IllegalStateException("Only cut/copy/paste supported but got " + command); + } + } else { + // Not sure what is selected -> copy/paste/cut selected entries + switch (command) { + case COPY: + getCurrentBasePanel().copy(); + break; + case CUT: + getCurrentBasePanel().cut(); + break; + case PASTE: + getCurrentBasePanel().paste(); + break; + default: + throw new IllegalStateException("Only cut/copy/paste supported but got " + command); + } + } } } } diff --git a/src/main/java/org/jabref/gui/fieldeditors/EditorTextField.java b/src/main/java/org/jabref/gui/fieldeditors/EditorTextField.java index 51cd466a784..6452c64957b 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/EditorTextField.java +++ b/src/main/java/org/jabref/gui/fieldeditors/EditorTextField.java @@ -8,6 +8,7 @@ import javafx.fxml.Initializable; import javafx.scene.control.ContextMenu; import javafx.scene.control.MenuItem; +import javafx.scene.control.TextField; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.HBox; @@ -15,7 +16,7 @@ import com.sun.javafx.scene.control.skin.TextFieldSkin; -public class EditorTextField extends javafx.scene.control.TextField implements Initializable, ContextMenuAddable { +public class EditorTextField extends TextField implements Initializable, ContextMenuAddable { public EditorTextField() { this(""); diff --git a/src/main/java/org/jabref/gui/fieldeditors/FieldEditor.java b/src/main/java/org/jabref/gui/fieldeditors/FieldEditor.java deleted file mode 100644 index 711b3ffc550..00000000000 --- a/src/main/java/org/jabref/gui/fieldeditors/FieldEditor.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.jabref.gui.fieldeditors; - -import java.awt.Color; - -import javax.swing.JComponent; - -/** - * FieldEditors is a common interface between the TextField and TextArea. - */ -public interface FieldEditor { - - String getFieldName(); - - /* - * Returns the component to be added to a container. Might be a JScrollPane - * or the component itself. - */ - JComponent getPane(); - - /* - * Returns the text component itself. - */ - Object getTextComponent(); - - default boolean hasFocus() { - if (getTextComponent() instanceof JComponent) { - return ((JComponent) getTextComponent()).hasFocus(); - } - return false; - } - - void setActiveBackgroundColor(); - - void setValidBackgroundColor(); - - void setInvalidBackgroundColor(); - - void setBackground(Color color); - - String getText(); - - /** - * Sets the given text on the current field editor and marks this text - * editor as modified. - * - * @param newText - */ - void setText(String newText); - - void append(String text); - - void requestFocus(); - - void setEnabled(boolean enabled); - - /** - * paste text into component, it should also take some selected text into - * account - */ - void paste(String textToInsert); - - /** - * normally implemented in JTextArea and JTextField - * - * @return - */ - String getSelectedText(); - - void undo(); - - void redo(); -} diff --git a/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFocusListener.java b/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFocusListener.java deleted file mode 100644 index 4c245020e65..00000000000 --- a/src/main/java/org/jabref/gui/fieldeditors/FieldEditorFocusListener.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.jabref.gui.fieldeditors; - -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; - -import javax.swing.JComponent; - -import org.jabref.gui.GUIGlobals; - -/** - * Focus listener that changes the color of the text area when it has focus. - */ -public class FieldEditorFocusListener implements FocusListener { - @Override - public void focusGained(FocusEvent event) { - if (event.getSource() instanceof FieldEditor) { - ((FieldEditor) event.getSource()).setActiveBackgroundColor(); - } else { - ((JComponent) event.getSource()).setBackground(GUIGlobals.activeBackgroundColor); - } - } - - @Override - public void focusLost(FocusEvent event) { - if (!(event.getSource() instanceof FieldEditor)) { - ((JComponent) event.getSource()).setBackground(GUIGlobals.validFieldBackgroundColor); - } - } -} diff --git a/src/main/java/org/jabref/gui/fieldeditors/TextField.java b/src/main/java/org/jabref/gui/fieldeditors/TextField.java deleted file mode 100644 index 66942a70756..00000000000 --- a/src/main/java/org/jabref/gui/fieldeditors/TextField.java +++ /dev/null @@ -1,183 +0,0 @@ -package org.jabref.gui.fieldeditors; - -import java.awt.Color; -import java.awt.event.ActionEvent; -import java.lang.reflect.InvocationTargetException; - -import javax.swing.AbstractAction; -import javax.swing.JComponent; -import javax.swing.SwingUtilities; -import javax.swing.text.Document; -import javax.swing.undo.CannotRedoException; -import javax.swing.undo.CannotUndoException; -import javax.swing.undo.UndoManager; - -import org.jabref.Globals; -import org.jabref.gui.GUIGlobals; -import org.jabref.gui.actions.Actions; -import org.jabref.gui.util.component.JTextFieldWithPlaceholder; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * An implementation of the FieldEditor backed by a JTextField. Used for single-line input, only BibTex key at the - * moment?! - */ -public class TextField extends JTextFieldWithPlaceholder implements FieldEditor { - - private static final Logger LOGGER = LoggerFactory.getLogger(TextField.class); - - private final String fieldName; - private UndoManager undo; - - public TextField(String fieldName, String content, boolean changeColorOnFocus) { - this(fieldName, content, changeColorOnFocus, ""); - } - - public TextField(String fieldName, String content, boolean changeColorOnFocus, String title) { - super(content, title); - - setupPasteListener(); - setupUndoRedo(); - - updateFont(); - - // Add the global focus listener, so a menu item can see if this field - // was focused when - // an action was called. - addFocusListener(Globals.getFocusListener()); - if (changeColorOnFocus) { - addFocusListener(new FieldEditorFocusListener()); - } - this.fieldName = fieldName; - setBackground(GUIGlobals.validFieldBackgroundColor); - setForeground(GUIGlobals.editorTextColor); - } - - @Override - public void setText(String t) { - super.setText(t); - if (undo != null) { - undo.discardAllEdits(); - } - } - - @Override - public void append(String text) { - setText(getText() + text); - } - - @Override - public String getFieldName() { - return fieldName; - } - - @Override - public JComponent getPane() { - return this; - } - - @Override - public JComponent getTextComponent() { - return this; - - } - - @Override - public void setActiveBackgroundColor() { - setBackgroundColor(GUIGlobals.activeBackgroundColor); - } - - @Override - public void setValidBackgroundColor() { - setBackgroundColor(GUIGlobals.validFieldBackgroundColor); - } - - @Override - public void setInvalidBackgroundColor() { - setBackgroundColor(GUIGlobals.invalidFieldBackgroundColor); - } - - private void setBackgroundColor(Color color) { - if (SwingUtilities.isEventDispatchThread()) { - setBackground(color); - } else { - try { - SwingUtilities.invokeAndWait(() -> setBackground(color)); - } catch (InvocationTargetException | InterruptedException e) { - LOGGER.info("Problem setting background color", e); - } - } - - } - - private void updateFont() { - setFont(GUIGlobals.currentFont); - } - - @Override - // Only replaces selected text if found - public void paste(String textToInsert) { - replaceSelection(textToInsert); - } - - @Override - public void undo() { - // Nothing - } - - @Override - public void redo() { - // Nothing - } - - private void setupPasteListener() { - // Bind paste command to KeyBinds.PASTE - getInputMap().put(Globals.getKeyPrefs().getKey(org.jabref.gui.keyboard.KeyBinding.PASTE), Actions.PASTE); - } - - private void setupUndoRedo() { - undo = new UndoManager(); - Document doc = getDocument(); - - // Listen for undo and redo events - doc.addUndoableEditListener(evt -> undo.addEdit(evt.getEdit())); - - // Create an undo action and add it to the text component - getActionMap().put("Undo", new AbstractAction("Undo") { - - @Override - public void actionPerformed(ActionEvent evt) { - try { - if (undo.canUndo()) { - undo.undo(); - } - } catch (CannotUndoException ignored) { - // Ignored - } - } - }); - - // Bind the undo action to ctl-Z - getInputMap().put(Globals.getKeyPrefs().getKey(org.jabref.gui.keyboard.KeyBinding.UNDO), "Undo"); - - // Create a redo action and add it to the text component - getActionMap().put("Redo", new AbstractAction(Actions.REDO.name()) { - - @Override - public void actionPerformed(ActionEvent evt) { - try { - if (undo.canRedo()) { - undo.redo(); - } - } catch (CannotRedoException ignored) { - // Ignored - } - } - }); - - // Bind the redo action to ctl-Y - getInputMap().put(Globals.getKeyPrefs().getKey(org.jabref.gui.keyboard.KeyBinding.REDO), "Redo"); - } -} diff --git a/src/main/java/org/jabref/gui/groups/GroupDialog.java b/src/main/java/org/jabref/gui/groups/GroupDialog.java index 043ee954af1..b233bd1fe86 100644 --- a/src/main/java/org/jabref/gui/groups/GroupDialog.java +++ b/src/main/java/org/jabref/gui/groups/GroupDialog.java @@ -39,7 +39,6 @@ import org.jabref.gui.Dialog; import org.jabref.gui.JabRefDialog; import org.jabref.gui.JabRefFrame; -import org.jabref.gui.fieldeditors.TextField; import org.jabref.gui.keyboard.KeyBinding; import org.jabref.gui.search.rules.describer.SearchDescribers; import org.jabref.gui.util.TooltipTextUtil; @@ -103,7 +102,7 @@ class GroupDialog extends JabRefDialog implements Dialog { // for KeywordGroup private final JTextField keywordGroupSearchField = new JTextField(GroupDialog.TEXTFIELD_LENGTH); - private final TextField keywordGroupSearchTerm = new TextField(FieldName.KEYWORDS, "", false); + private final JTextField keywordGroupSearchTerm = new JTextField(GroupDialog.TEXTFIELD_LENGTH); private final JCheckBox keywordGroupCaseSensitive = new JCheckBox(Localization.lang("Case sensitive")); private final JCheckBox keywordGroupRegExp = new JCheckBox(Localization.lang("regular expression")); // for SearchGroup diff --git a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java index d69733a48d5..e0fb4494af1 100644 --- a/src/main/java/org/jabref/gui/search/GlobalSearchBar.java +++ b/src/main/java/org/jabref/gui/search/GlobalSearchBar.java @@ -274,7 +274,6 @@ public void endSearch() { if (currentBasePanel != null) { clearSearch(); MainTable mainTable = frame.getCurrentBasePanel().getMainTable(); - //Globals.getFocusListener().setFocused(mainTable); mainTable.requestFocus(); //SwingUtilities.invokeLater(() -> mainTable.ensureVisible(mainTable.getSelectedRow())); }