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