// License: WTFPL. For details, see LICENSE file.
package geochat;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.KeyboardFocusManager;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import javax.swing.JComponent;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.text.DefaultEditorKit;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
/**
* JTextField tweaked to work in a JOSM panel. It prevents unwanted keystrokes
* to be caught by the editor.
*
* @author zverik
*/
public class JPanelTextField extends JTextField {
public JPanelTextField() {
setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, new HashSet<KeyStroke>());
PopupMenuLauncher launcher = new PopupMenuLauncher(createEditMenu());
addMouseListener(launcher);
standardKeys = getInputMap(JComponent.WHEN_FOCUSED).allKeys();
}
private JPopupMenu createEditMenu() {
JPopupMenu menu = new JPopupMenu();
menu.add(createMenuItem(DefaultEditorKit.cutAction, tr("Cut")));
menu.add(createMenuItem(DefaultEditorKit.copyAction, tr("Copy")));
menu.add(createMenuItem(DefaultEditorKit.pasteAction, tr("Paste")));
menu.add(createMenuItem(DefaultEditorKit.selectAllAction, tr("Select All")));
return menu;
}
private JMenuItem createMenuItem(String action, String label) {
JMenuItem item = new JMenuItem(getActionMap().get(action));
item.setText(label);
return item;
}
// list of "standard" OS keys for JTextFiels = cursor moving, selection, copy/paste
private final KeyStroke[] standardKeys;
private static final int MODIFIERS_MASK =
InputEvent.META_DOWN_MASK | InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK;
@Override
protected void processKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_ENTER) {
String text = getText();
if (text.length() > 0) {
processEnter(text);
setText("");
}
} else if (code == KeyEvent.VK_TAB) {
String text = getText();
int caret = getCaretPosition();
int start = caret - 1;
while (start >= 0 && Character.isJavaIdentifierPart(text.charAt(start))) {
start--;
}
start++;
if (start < caret) {
String word = text.substring(start, caret);
String complete = word == null ? null : autoComplete(word, start == 0);
if (complete != null && !complete.equals(word)) {
StringBuilder sb = new StringBuilder();
if (start > 0)
sb.append(text.substring(0, start));
sb.append(complete);
if (caret < text.length())
sb.append(text.substring(caret));
setText(sb.toString());
setCaretPosition(start + complete.length());
}
}
} else if (code == KeyEvent.VK_ESCAPE) {
if (Main.map != null && Main.map.mapView != null)
Main.map.mapView.requestFocus();
}
boolean keyIsStandard = false;
for (KeyStroke ks: standardKeys) {
if (code == ks.getKeyCode() &&
(e.getModifiersEx() & MODIFIERS_MASK) == (ks.getModifiers() & MODIFIERS_MASK)) {
keyIsStandard = true;
break;
}
}
// Do not pass other events to JOSM
if (!keyIsStandard) {
e.consume();
}
}
super.processKeyEvent(e);
}
/**
* Process VK_ENTER. Override this to submit the text.
*
* @param text Contents of the text field.
*/
protected void processEnter(String text) { }
/**
* Autocomplete the word.
* @param word Partly typed word.
* @return The whole word.
*/
protected String autoComplete(String word, boolean atStart) {
return word;
}
}