diff --git a/src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedComponent.java b/src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedComponent.java
new file mode 100644
index 0000000000..a792c63749
--- /dev/null
+++ b/src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedComponent.java
@@ -0,0 +1,158 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.widgets;
+
+import java.awt.Component;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.util.List;
+import java.util.Set;
+
+import javax.swing.Action;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.KeyStroke;
+
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.gui.MainApplication;
+import org.openstreetmap.josm.tools.Pair;
+import org.openstreetmap.josm.tools.Shortcut;
+import org.openstreetmap.josm.tools.annotations.PrivateMethod;
+
+/**
+ * An interface for components with code that can be used for disabling shortcuts while they hold focus.
+ *
+ * Warning: On migration to Java 9+, all methods marked
+ * @author Taylor Smock
+ * @since xxx (code extracted for {@link DisableShortcutsOnFocusGainedTextField}
+ */
+public interface DisableShortcutsOnFocusGainedComponent extends FocusListener {
+
+    @Override
+    default void focusGained(FocusEvent e) {
+        disableMenuActions();
+        unregisterActionShortcuts();
+    }
+
+    @Override
+    default void focusLost(FocusEvent e) {
+        restoreActionShortcuts();
+        restoreMenuActions();
+    }
+
+    /**
+     * Get the unregistered action shortcuts.
+     * This should not be used outside the {@link DisableShortcutsOnFocusGainedComponent} interface.
+     * @return The list of unregistered action shortcuts (modifiable)
+     */
+    List<Pair<Action, Shortcut>> getUnregisteredActionShortcuts();
+
+    /**
+     * Get the disabled menu action list
+     * This should not be used outside the {@link DisableShortcutsOnFocusGainedComponent} interface.
+     * @return The list of disabled menu actions (modifiable)
+     */
+    Set<JosmAction> getDisabledMenuActions();
+
+    /**
+     * Disables all relevant menu actions.
+     * @see #hasToBeDisabled
+     */
+    @PrivateMethod("Was protected")
+    default void disableMenuActions() {
+        getDisabledMenuActions().clear();
+        for (int i = 0; i < MainApplication.getMenu().getMenuCount(); i++) {
+            JMenu menu = MainApplication.getMenu().getMenu(i);
+            if (menu != null) {
+                for (int j = 0; j < menu.getItemCount(); j++) {
+                    JMenuItem item = menu.getItem(j);
+                    if (item != null) {
+                        Action action = item.getAction();
+                        if (action instanceof JosmAction && action.isEnabled()) {
+                            Shortcut shortcut = ((JosmAction) action).getShortcut();
+                            if (shortcut != null) {
+                                KeyStroke ks = shortcut.getKeyStroke();
+                                if (hasToBeDisabled(ks)) {
+                                    action.setEnabled(false);
+                                    getDisabledMenuActions().add((JosmAction) action);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Unregisters all relevant action shortcuts.
+     * @see #hasToBeDisabled
+     */
+    @PrivateMethod("Was protected")
+    default void unregisterActionShortcuts() {
+        getUnregisteredActionShortcuts().clear();
+        // Unregister all actions with Shift modifier or without modifiers to avoid them to be triggered by typing in this text field
+        for (Shortcut shortcut : Shortcut.listAll()) {
+            KeyStroke ks = shortcut.getKeyStroke();
+            if (hasToBeDisabled(ks)) {
+                Action action = MainApplication.getRegisteredActionShortcut(shortcut);
+                if (action != null) {
+                    MainApplication.unregisterActionShortcut(action, shortcut);
+                    getUnregisteredActionShortcuts().add(new Pair<>(action, shortcut));
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns true if the given shortcut has Shift modifier or no modifier and is not an actions key.
+     * @param ks key stroke
+     * @return {@code true} if the given shortcut has to be disabled
+     * @see KeyEvent#isActionKey()
+     */
+    @PrivateMethod("Was protected")
+    default boolean hasToBeDisabled(KeyStroke ks) {
+        if (this instanceof Component) {
+            return ks != null && (ks.getModifiers() == 0 || isOnlyShift(ks.getModifiers())) && !new KeyEvent((Component) this,
+                    KeyEvent.KEY_PRESSED, 0, ks.getModifiers(), ks.getKeyCode(), ks.getKeyChar()).isActionKey();
+        }
+        throw new UnsupportedOperationException(this.getClass().getSimpleName() + " is not an instanceof Component");
+    }
+
+    /**
+     * Check if the modifiers is only shift
+     * @param modifiers The modifiers to check
+     * @return {@code true} if the only modifier is {@link InputEvent#SHIFT_DOWN_MASK}
+     */
+    @PrivateMethod("Was private")
+    static boolean isOnlyShift(int modifiers) {
+        return (modifiers & InputEvent.SHIFT_DOWN_MASK) != 0
+                && (modifiers & InputEvent.CTRL_DOWN_MASK) == 0
+                && (modifiers & InputEvent.ALT_DOWN_MASK) == 0
+                && (modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) == 0
+                && (modifiers & InputEvent.META_DOWN_MASK) == 0;
+    }
+
+    /**
+     * Restore all actions previously disabled
+     */
+    @PrivateMethod("Was protected")
+    default void restoreMenuActions() {
+        for (JosmAction a : getDisabledMenuActions()) {
+            a.setEnabled(true);
+        }
+        getDisabledMenuActions().clear();
+    }
+
+    /**
+     * Restore all action shortcuts previously unregistered
+     */
+    @PrivateMethod("Was protected")
+    default void restoreActionShortcuts() {
+        for (Pair<Action, Shortcut> p : getUnregisteredActionShortcuts()) {
+            MainApplication.registerActionShortcut(p.a, p.b);
+        }
+        getUnregisteredActionShortcuts().clear();
+    }
+}
diff --git a/src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedTextField.java b/src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedTextField.java
index 13e8e687f8..b035615d2c 100644
--- a/src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedTextField.java
+++ b/src/org/openstreetmap/josm/gui/widgets/DisableShortcutsOnFocusGainedTextField.java
@@ -2,21 +2,15 @@
 package org.openstreetmap.josm.gui.widgets;
 
 import java.awt.event.FocusEvent;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
 import javax.swing.Action;
-import javax.swing.JMenu;
-import javax.swing.JMenuItem;
-import javax.swing.KeyStroke;
 import javax.swing.text.Document;
 
 import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -26,7 +20,7 @@ import org.openstreetmap.josm.tools.Shortcut;
  * This allows to include text fields in toggle dialogs (needed for relation filter).
  * @since 5696
  */
-public class DisableShortcutsOnFocusGainedTextField extends JosmTextField {
+public class DisableShortcutsOnFocusGainedTextField extends JosmTextField implements DisableShortcutsOnFocusGainedComponent {
 
     /**
      * Constructs a new <code>TextField</code>. A default model is created,
@@ -97,101 +91,23 @@ public class DisableShortcutsOnFocusGainedTextField extends JosmTextField {
     @Override
     public void focusGained(FocusEvent e) {
         super.focusGained(e);
-        disableMenuActions();
-        unregisterActionShortcuts();
+        DisableShortcutsOnFocusGainedComponent.super.focusGained(e);
     }
 
     @Override
     public void focusLost(FocusEvent e) {
         super.focusLost(e);
-        restoreActionShortcuts();
-        restoreMenuActions();
+        DisableShortcutsOnFocusGainedComponent.super.focusLost(e);
     }
 
-    /**
-     * Disables all relevant menu actions.
-     * @see #hasToBeDisabled
-     */
-    protected void disableMenuActions() {
-        disabledMenuActions.clear();
-        for (int i = 0; i < MainApplication.getMenu().getMenuCount(); i++) {
-            JMenu menu = MainApplication.getMenu().getMenu(i);
-            if (menu != null) {
-                for (int j = 0; j < menu.getItemCount(); j++) {
-                    JMenuItem item = menu.getItem(j);
-                    if (item != null) {
-                        Action action = item.getAction();
-                        if (action instanceof JosmAction && action.isEnabled()) {
-                            Shortcut shortcut = ((JosmAction) action).getShortcut();
-                            if (shortcut != null) {
-                                KeyStroke ks = shortcut.getKeyStroke();
-                                if (hasToBeDisabled(ks)) {
-                                    action.setEnabled(false);
-                                    disabledMenuActions.add((JosmAction) action);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Unregisters all relevant action shortcuts.
-     * @see #hasToBeDisabled
-     */
-    protected void unregisterActionShortcuts() {
-        unregisteredActionShortcuts.clear();
-        // Unregister all actions with Shift modifier or without modifiers to avoid them to be triggered by typing in this text field
-        for (Shortcut shortcut : Shortcut.listAll()) {
-            KeyStroke ks = shortcut.getKeyStroke();
-            if (hasToBeDisabled(ks)) {
-                Action action = MainApplication.getRegisteredActionShortcut(shortcut);
-                if (action != null) {
-                    MainApplication.unregisterActionShortcut(action, shortcut);
-                    unregisteredActionShortcuts.add(new Pair<>(action, shortcut));
-                }
-            }
-        }
-    }
-
-    /**
-     * Returns true if the given shortcut has Shift modifier or no modifier and is not an actions key.
-     * @param ks key stroke
-     * @return {@code true} if the given shortcut has to be disabled
-     * @see KeyEvent#isActionKey()
-     */
-    protected boolean hasToBeDisabled(KeyStroke ks) {
-        return ks != null && (ks.getModifiers() == 0 || isOnlyShift(ks.getModifiers())) && !new KeyEvent(
-                this, KeyEvent.KEY_PRESSED, 0, ks.getModifiers(), ks.getKeyCode(), ks.getKeyChar()).isActionKey();
-    }
-
-    private static boolean isOnlyShift(int modifiers) {
-        return (modifiers & InputEvent.SHIFT_DOWN_MASK) != 0
-                && (modifiers & InputEvent.CTRL_DOWN_MASK) == 0
-                && (modifiers & InputEvent.ALT_DOWN_MASK) == 0
-                && (modifiers & InputEvent.ALT_GRAPH_DOWN_MASK) == 0
-                && (modifiers & InputEvent.META_DOWN_MASK) == 0;
+    @Override
+    public List<Pair<Action, Shortcut>> getUnregisteredActionShortcuts() {
+        return this.unregisteredActionShortcuts;
     }
 
-    /**
-     * Restore all actions previously disabled
-     */
-    protected void restoreMenuActions() {
-        for (JosmAction a : disabledMenuActions) {
-            a.setEnabled(true);
-        }
-        disabledMenuActions.clear();
+    @Override
+    public Set<JosmAction> getDisabledMenuActions() {
+        return this.disabledMenuActions;
     }
 
-    /**
-     * Restore all action shortcuts previously unregistered
-     */
-    protected void restoreActionShortcuts() {
-        for (Pair<Action, Shortcut> p : unregisteredActionShortcuts) {
-            MainApplication.registerActionShortcut(p.a, p.b);
-        }
-        unregisteredActionShortcuts.clear();
-    }
 }
diff --git a/src/org/openstreetmap/josm/tools/annotations/PrivateMethod.java b/src/org/openstreetmap/josm/tools/annotations/PrivateMethod.java
new file mode 100644
index 0000000000..7e7e4554ba
--- /dev/null
+++ b/src/org/openstreetmap/josm/tools/annotations/PrivateMethod.java
@@ -0,0 +1,16 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.tools.annotations;
+
+/**
+ * This annotation marks methods that will become private when JOSM migrates the codebase to JOSM 9+.
+ * This is typically used in interfaces.
+ * @author Taylor Smock
+ * @since xxx
+ */
+public @interface PrivateMethod {
+    /**
+     * The reason why this method will become private
+     * @return The reason
+     */
+    String value() default "";
+}
diff --git a/src/org/openstreetmap/josm/tools/annotations/package-info.java b/src/org/openstreetmap/josm/tools/annotations/package-info.java
new file mode 100644
index 0000000000..eeb988cf11
--- /dev/null
+++ b/src/org/openstreetmap/josm/tools/annotations/package-info.java
@@ -0,0 +1,6 @@
+// License: GPL. For details, see LICENSE file.
+
+/**
+ * Provides the annotations to mark items for future changes
+ */
+package org.openstreetmap.josm.tools.annotations;
