org.microemu.device.j2se.J2SEInputMethod Maven / Gradle / Ivy
/*
* MicroEmulator
* Copyright (C) 2001 Bartek Teodorczyk
*
* It is licensed under the following two licenses as alternatives:
* 1. GNU Lesser General Public License (the "LGPL") version 2.1 or any newer version
* 2. Apache License (the "AL") Version 2.0
*
* You may not use this file except in compliance with at least one of
* the above two licenses.
*
* You may obtain a copy of the LGPL at
* http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
*
* You may obtain a copy of the AL at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the LGPL or the AL for the specific language governing permissions and
* limitations.
*
* @version $Id: J2SEInputMethod.java 1907 2009-01-12 13:19:36Z barteo $
*/
package org.microemu.device.j2se;
import java.awt.event.KeyEvent;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.TextField;
import org.microemu.DisplayAccess;
import org.microemu.MIDletAccess;
import org.microemu.MIDletBridge;
import org.microemu.device.DeviceFactory;
import org.microemu.device.InputMethod;
import org.microemu.device.InputMethodEvent;
import org.microemu.device.impl.ButtonDetaultDeviceKeyCodes;
import org.microemu.device.impl.ButtonName;
import org.microemu.device.impl.InputMethodImpl;
import org.microemu.device.impl.SoftButton;
import org.microemu.device.impl.ui.CommandManager;
import org.microemu.util.ThreadUtils;
public class J2SEInputMethod extends InputMethodImpl {
private boolean eventAlreadyConsumed;
private Timer keyReleasedDelayTimer;
private List repeatModeKeyCodes = new Vector();
private class KeyReleasedDelayTask extends TimerTask {
private int repeatModeKeyCode;
KeyReleasedDelayTask(int repeatModeKeyCode) {
this.repeatModeKeyCode = repeatModeKeyCode;
}
public void run() {
if (repeatModeKeyCode != Integer.MIN_VALUE) {
MIDletAccess ma = MIDletBridge.getMIDletAccess();
if (ma == null) {
return;
}
DisplayAccess da = ma.getDisplayAccess();
if (da == null) {
return;
}
da.keyReleased(repeatModeKeyCode);
eventAlreadyConsumed = false;
repeatModeKeyCode = Integer.MIN_VALUE;
}
}
};
public J2SEInputMethod() {
super();
// TODO When InputMethod will be removed from EmulatorContext add:
// if (DeviceFactory.getDevice().hasRepeatEvents()) {
keyReleasedDelayTimer = ThreadUtils.createTimer("InputKeyReleasedDelayTimer");
}
/**
* Gets the game action associated with the given key code of the device.
*
* @return the game action corresponding to this key, or 0
if
* none
*/
public int getGameAction(int keyCode) {
for (Iterator it = DeviceFactory.getDevice().getButtons().iterator(); it.hasNext();) {
J2SEButton button = (J2SEButton) it.next();
if (button.getKeyCode() == keyCode) {
return ButtonDetaultDeviceKeyCodes.getGameAction(button.getFunctionalName());
}
}
return 0;
}
/**
*
*
* @return a key code corresponding to this game action
* @throws IllegalArgumentException
* if gameAction
is not a valid game action
*/
public int getKeyCode(int gameAction) {
ButtonName name = ButtonDetaultDeviceKeyCodes.getButtonNameByGameAction(gameAction);
return J2SEDeviceButtonsHelper.getButton(name).getKeyCode();
}
/**
* @return a string name for the key
* @throws IllegalArgumentException
* if keyCode
is not a valid key code
*/
public String getKeyName(int keyCode) throws IllegalArgumentException {
for (Iterator it = DeviceFactory.getDevice().getButtons().iterator(); it.hasNext();) {
J2SEButton button = (J2SEButton) it.next();
if (button.getKeyCode() == keyCode) {
return button.getName();
}
}
return Character.toString((char) keyCode);
}
protected boolean fireInputMethodListener(J2SEButton button, char keyChar) {
MIDletAccess ma = MIDletBridge.getMIDletAccess();
if (ma == null) {
return false;
}
DisplayAccess da = ma.getDisplayAccess();
if (da == null) {
return false;
}
int keyCode = keyChar;
if (button != null && keyChar == '\0') {
keyCode = button.getKeyCode();
}
if (inputMethodListener == null) {
da.keyPressed(keyCode);
return true;
}
if (button == null) {
return true;
}
ButtonName functionalName = button.getFunctionalName();
if (functionalName == ButtonName.UP || functionalName == ButtonName.DOWN) {
da.keyPressed(button.getKeyCode());
return true;
}
int caret = inputMethodListener.getCaretPosition();
if (button.isModeChange()) {
switch (inputMethodListener.getConstraints() & TextField.CONSTRAINT_MASK) {
case TextField.ANY:
case TextField.EMAILADDR:
case TextField.URL:
if (getInputMode() == InputMethod.INPUT_123) {
setInputMode(InputMethod.INPUT_ABC_UPPER);
} else if (getInputMode() == InputMethod.INPUT_ABC_UPPER) {
setInputMode(InputMethod.INPUT_ABC_LOWER);
} else if (getInputMode() == InputMethod.INPUT_ABC_LOWER) {
setInputMode(InputMethod.INPUT_123);
}
synchronized (this) {
if (lastButton != null) {
caret++;
lastButton = null;
lastButtonCharIndex = -1;
}
}
InputMethodEvent event = new InputMethodEvent(InputMethodEvent.CARET_POSITION_CHANGED, caret,
inputMethodListener.getText());
inputMethodListener.caretPositionChanged(event);
break;
}
return true;
}
if (functionalName == ButtonName.LEFT || functionalName == ButtonName.RIGHT) {
synchronized (this) {
if ((functionalName == ButtonName.LEFT) && caret > 0) {
caret--;
} else if ((functionalName == ButtonName.RIGHT) && caret < inputMethodListener.getText().length()) {
caret++;
}
lastButton = null;
lastButtonCharIndex = -1;
}
InputMethodEvent event = new InputMethodEvent(InputMethodEvent.CARET_POSITION_CHANGED, caret,
inputMethodListener.getText());
inputMethodListener.caretPositionChanged(event);
return true;
}
if (functionalName == ButtonName.BACK_SPACE) {
String tmp = "";
synchronized (this) {
if (lastButton != null) {
caret++;
lastButton = null;
lastButtonCharIndex = -1;
}
if (caret > 0) {
caret--;
if (caret > 0) {
tmp += inputMethodListener.getText().substring(0, caret);
}
if (caret < inputMethodListener.getText().length() - 1) {
tmp += inputMethodListener.getText().substring(caret + 1);
}
}
}
if (!validate(tmp, inputMethodListener.getConstraints())) {
return true;
}
InputMethodEvent event = new InputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, caret, tmp);
inputMethodListener.inputMethodTextChanged(event);
event = new InputMethodEvent(InputMethodEvent.CARET_POSITION_CHANGED, caret, tmp);
inputMethodListener.caretPositionChanged(event);
return true;
}
if (functionalName == ButtonName.DELETE) {
String tmp = inputMethodListener.getText();
synchronized (this) {
if (lastButton != null) {
lastButton = null;
lastButtonCharIndex = -1;
}
if (caret != inputMethodListener.getText().length()) {
tmp = inputMethodListener.getText().substring(0, caret)
+ inputMethodListener.getText().substring(caret + 1);
}
}
if (!validate(tmp, inputMethodListener.getConstraints())) {
return true;
}
InputMethodEvent event = new InputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, caret, tmp);
inputMethodListener.inputMethodTextChanged(event);
event = new InputMethodEvent(InputMethodEvent.CARET_POSITION_CHANGED, caret, tmp);
inputMethodListener.caretPositionChanged(event);
return true;
}
if (inputMethodListener.getText().length() < maxSize) {
StringBuffer editText = new StringBuffer(inputMethodListener.getText());
synchronized (this) {
lastButtonCharIndex++;
char[] buttonChars = filterConstraints(filterInputMode(button.getChars(getInputMode())));
if (keyChar != '\0') {
// Pass through letters and characters typed on keyboard but
// not numbers that are buttons keys (presumably).
editText.append(keyChar);
caret++;
lastButton = null;
lastButtonCharIndex = -1;
} else if (buttonChars.length > 0) {
if (lastButtonCharIndex == buttonChars.length) {
if (buttonChars.length == 1) {
if (lastButton != null) {
caret++;
}
lastButton = null;
} else {
lastButtonCharIndex = 0;
}
}
if (lastButton != button) {
if (lastButton != null) {
caret++;
}
if (editText.length() < caret) {
editText.append(buttonChars[0]);
} else {
editText.insert(caret, buttonChars[0]);
}
lastButton = button;
lastButtonCharIndex = 0;
} else {
editText.setCharAt(caret, buttonChars[lastButtonCharIndex]);
lastButton = button;
}
} else {
lastButton = null;
lastButtonCharIndex = -1;
}
resetKey = false;
notify();
}
if (!validate(editText.toString(), inputMethodListener.getConstraints())) {
return false;
}
InputMethodEvent event = new InputMethodEvent(InputMethodEvent.INPUT_METHOD_TEXT_CHANGED, caret, editText
.toString());
inputMethodListener.inputMethodTextChanged(event);
}
return false;
}
public void buttonTyped(J2SEButton button) {
if (eventAlreadyConsumed) {
return;
}
}
public void clipboardPaste(String str) {
if (inputMethodListener != null && inputMethodListener.getText() != null
&& ((inputMethodListener.getText().length() + str.length()) <= maxSize)) {
insertText(str);
}
eventAlreadyConsumed = true;
}
public void buttonPressed(J2SEButton button, char keyChar) {
int keyCode = keyChar;
if (button != null && keyChar == '\0') {
keyCode = button.getKeyCode();
}
eventAlreadyConsumed = false;
if (DeviceFactory.getDevice().hasRepeatEvents()) {
if (repeatModeKeyCodes.contains(new Integer(keyCode))) {
MIDletAccess ma = MIDletBridge.getMIDletAccess();
if (ma == null) {
return;
}
DisplayAccess da = ma.getDisplayAccess();
if (da == null) {
return;
}
da.keyRepeated(keyCode);
eventAlreadyConsumed = true;
return;
} else {
repeatModeKeyCodes.add(new Integer(keyCode));
}
}
// invoke any associated commands, but send the raw key codes instead
boolean rawSoftKeys = DeviceFactory.getDevice().getDeviceDisplay().isFullScreenMode();
if (button instanceof SoftButton && !rawSoftKeys) {
Command cmd = ((SoftButton) button).getCommand();
if (cmd != null) {
MIDletAccess ma = MIDletBridge.getMIDletAccess();
if (ma == null) {
return;
}
DisplayAccess da = ma.getDisplayAccess();
if (da == null) {
return;
}
if (cmd.equals(CommandManager.CMD_MENU)) {
CommandManager.getInstance().commandAction(cmd);
} else {
da.commandAction(cmd, da.getCurrent());
}
eventAlreadyConsumed = true;
return;
}
}
if (fireInputMethodListener(button, keyChar)) {
eventAlreadyConsumed = true;
return;
}
}
public void buttonReleased(J2SEButton button, char keyChar) {
int keyCode = keyChar;
if (button != null && keyChar == '\0') {
keyCode = button.getKeyCode();
}
if (DeviceFactory.getDevice().hasRepeatEvents()) {
repeatModeKeyCodes.remove(new Integer(keyCode));
keyReleasedDelayTimer.schedule(new KeyReleasedDelayTask(keyCode), 50);
} else {
MIDletAccess ma = MIDletBridge.getMIDletAccess();
if (ma == null) {
return;
}
DisplayAccess da = ma.getDisplayAccess();
if (da == null) {
return;
}
da.keyReleased(keyCode);
eventAlreadyConsumed = false;
}
}
public J2SEButton getButton(KeyEvent ev) {
J2SEButton button = J2SEDeviceButtonsHelper.getButton(ev);
if (button != null) {
return button;
}
if (getInputMode() != INPUT_123) {
for (Enumeration e = DeviceFactory.getDevice().getButtons().elements(); e.hasMoreElements();) {
button = (J2SEButton) e.nextElement();
if (button.isChar(ev.getKeyChar(), getInputMode())) {
return button;
}
}
}
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy