001    // License: GPL. See LICENSE file for details.
002    package org.openstreetmap.josm.gui.util;
003    
004    import javax.swing.ComponentInputMap;
005    import javax.swing.InputMap;
006    import javax.swing.JComponent;
007    import javax.swing.KeyStroke;
008    
009    import org.openstreetmap.josm.Main;
010    
011    /**
012     * Make shortcuts from main window work in dialog windows.
013     *
014     * It's not possible to simply set component input map parent to be Main.contentPane.getInputMap
015     * because there is check in setParent that InputMap is for the same component.
016     * Yes, this is a hack.
017     * Another possibility would be simply copy InputMap, but that would require to
018     * keep copies synchronized when some shortcuts are changed later.
019     */
020    public class RedirectInputMap extends ComponentInputMap {
021    
022        private final InputMap target;
023    
024        public RedirectInputMap(JComponent component, InputMap target) {
025            super(component);
026            this.target = target;
027        }
028    
029        @Override
030        public Object get(KeyStroke keyStroke) {
031            return target.get(keyStroke);
032        }
033    
034        @Override
035        public KeyStroke[] keys() {
036            return target.keys();
037        }
038    
039        @Override
040        public int size() {
041            return target.size();
042        }
043    
044        @Override
045        public KeyStroke[] allKeys() {
046            return target.allKeys();
047        }
048    
049        @Override
050        public void put(KeyStroke keyStroke, Object actionMapKey) {
051            throw new UnsupportedOperationException();
052        }
053    
054        @Override
055        public void remove(KeyStroke key) {
056            throw new UnsupportedOperationException();
057        }
058    
059        @Override
060        public void clear() {
061            throw new UnsupportedOperationException();
062        }
063    
064        public static void redirect(JComponent source, JComponent target) {
065            InputMap lastParent = source.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
066            while (lastParent.getParent() != null) {
067                lastParent = lastParent.getParent();
068            }
069            lastParent.setParent(new RedirectInputMap(source, target.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)));
070            source.getActionMap().setParent(target.getActionMap());
071        }
072    }