I have a problem with typing in Robot Class. I want the robot to type something the
user has entered. The robot for some reason can't type some of the characters. Here is my type code:
public void type(String s,Robot robot) {
byte[] stringBytes = s.getBytes();
for (byte b : stringBytes) {
int code = b;
if (code > 96 && code < 123)
code = code - 32;
robot.keyPress(code);
robot.keyRelease(code);
}
}
how can i fix this problem?
If you want to "type back what the user entered", then surely you should be capturing a set of KeyEvent objects, and not a String. There is not a key for every String character, far from it! (for instance you need to press 'shift' to input a colon, so that's two key presses and not one)
Robot expects key codes defined in KeyEvent.
Related
I have problem with press a special letter (Turkish etc.) via java robot class. I hava a method to press keys which works as alt+keycode. I cant convert some special letters to current keycode. So how can I solve it. Thanx
For Example:
KeyStroke ks = KeyStroke.getKeyStroke('ö', 0);
System.out.println(ks.getKeyCode());
Output : 246
// So alt+0246='ö'
//but if I convert 'ş' to keycode
//Output is 351 . So alt+351= '_' and alt+0351= '_'
//What is the Correct combination for 'ş'. same for 'Ş', 'ş','Ğ', 'ğ', 'İ', 'ı', 'Ə', 'ə'
KeyPress:
public void altNumpad(int... numpadCodes) {
if (numpadCodes.length == 0) {
return;
}
robot.keyPress(VK_ALT);
for (int NUMPAD_KEY : numpadCodes) {
robot.keyPress(NUMPAD_KEY);
robot.keyRelease(NUMPAD_KEY);
}
robot.keyRelease(VK_ALT);
}
The character numbers are defiunied in the Unicode standard. The are also used in HTML, therefore you can use this table.
Anyway if you see the character in the source code depends on the fact that the editor interprets the file correctly (UTF-8 is preferred).
Second the used editor must have a font installed that contains these characters. Hence if you type alt+0351 and get and '_' this may just be a replacement character indicating that the font misses this character.
And in the end you should tell the Java compiler that the source code is UTF-8 - just to make sure (javac -encoding utf8).
I am not sure why you did
KeyStroke ks = KeyStroke.getKeyStroke('ö', 0);
Because java docs say,
public static KeyStroke getKeyStroke(Character keyChar,
int modifiers)
//Use 0 to specify no modifiers.
you need to pass a modifier other than 0 to the overload.
You should try to pass a modification like,
java.awt.event.InputEvent.ALT_DOWN_MASK
So probably should try,
KeyStroke ks = KeyStroke.getKeyStroke('ö', java.awt.event.InputEvent.ALT_DOWN_MASK);
Java doc as reference: http://docs.oracle.com/javase/7/docs/api/javax/swing/KeyStroke.html#getKeyStroke(char)
If you cannot properly get a output from that then you should consider the fact the character is UTF-8
This might help you in that regard, Java, Using Scanner to input characters as UTF-8, can't print text
I know this is a late answer but here it is how I handle this problem for Turkish QWERTY keyboard
static void writeRobotWrite(Robot robot, String keys) throws InterruptedException {
....
try {
robot.keyPress(keyCode);
robot.delay(20);
robot.keyRelease(keyCode);
robot.delay(20);
}catch (IllegalArgumentException e)
{
pressUnicode(c, robot);
}
}
}
Basically when I got undefined keyCode for Robot I call pressUnicode function which is:
static void pressUnicode(char c, Robot robot)
{
String cantRecognize = ""+c;
StringSelection selection = new StringSelection(cantRecognize);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(selection, null);
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
}
Simply I'm just copying and pasting the character. This is working for all undefined characters. :)
I have problem with pressing a special letter (Chinese, cyrillic etc.) via java robot class. I hava a method to press keys which works as alt+keycode. I cant convert some special letters to corrent keycode. So how can I solve it. Thanx
For Example:
KeyStroke ks = KeyStroke.getKeyStroke('a', 0);
System.out.println(ks.getKeyCode());
Output : 97
//but if I convert 'ş' to keycode
//Output is 351 . So alt+351= '_' The Correct combination is alt+0254 for 'ş'
KeyPress:
public static void doType(int a, int keyCodes)
throws AWTException {
Robot robot = new Robot();
robot.keyPress(VK_ALT);
robot.keyPress(keyCodes);
robot.keyRelease(keyCodes);
robot.keyRelease(VK_ALT);
}
'a' evaluates to 97 in UTF-8.
KeyStroke.getKeyCode()
simply returns an integer representation of 'a'.
I want to collect keyboard input and append it together in a java StringBuilder, but using LWJGL's Keyboard event, i end up fetching more than I wish, like Shift, CapsLock, Escape, F1 to F12, Enter, even punctuation etc.. These keys also have key ID's, but by appending them, they are printed as a square (unrecognized character i believe).
My goal is to ignore these non-printable keys without having to create a giant array with all these unwanted keys. Is there any way to do so?
P.S. Mind that i wish the common symbols like \,.-< etc. to still be considered into the string, like any text editor would.
Here's an example of what you could use. This example is then used as an inner class and you use it in stead of a regular ActionListener on a component. This example catches the keycode of the event (using KeyEvent). I placed some examples you asked in your questions, I'm sure you'll find more if needed.
You should append a custom string to your existing string in every case of the switch statement.
public class CustomListener extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
try {
int keyCode = e.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_SHIFT:
//Append a string to your existing string
break;
case KeyEvent.VK_F1:
//Append a string to your existing string
break;
case KeyEvent.VK_CAPS_LOCK:
//Append a string to your existing string
break;
case KeyEvent.VK_ENTER:
//Append a string to your existing string
break;
}
}
} catch (NullPointerException e1) {
e1.printStackTrace();
}
}
}
Thanks to Mark W I just found out that the ASCII range from 32 to 126 and 128 to 255 covers, i believe, every single character that is commonly printed in the everyday text-editors. Thanks a bunch :)
Here is a minimal code chunk that might be useful for someone using lwjgl
private StringBuilder text;
private void updateInput()
{
while (Keyboard.next())
{
if (Keyboard.getEventKeyState())
{
// get key info
int key = Keyboard.getEventKey();
char ch = Keyboard.getEventCharacter();
int ascii = (int) ch;
// delete case
if(key == Keyboard.KEY_BACK)
text.setLength(Math.max(0, text.length() - 1));
// append if common char
if((ascii >= 32 && ascii <= 126) || (ascii >= 128 && ascii <= 255))
text.append(ch);
}
}
}
first time making a question.
What I want is a way of every time the user presses a key on the console certains actions take place. Like, as he types a word, I want at every keypress for a String formed by all the keys he's already pressed to be printed, concatenated to the newly pressed key. As in:
a
You typed: a
b
You typed: ab
c
You typed: abc
d
You typed: abcd
e
You typed: abcde
I'm trying to do this with the following code:
try (BufferedReader input = new BufferedReader(
new InputStreamReader(System.in, "UTF-8"))) {
char c = 0;
String s = "";
while( (c = (char) input.read() ) != 13) {
s += c;
System.out.println("You typed: " + s);
}
}
I get what I want, but just after I press the Enter key, not as every key pressed on the console:
foobar
You typed: f
You typed: fo
You typed: foo
You typed: foob
You typed: fooba
You typed: foobar
Thanks in advance.
It looks like someone else has asked this question. It also looks like that consensus is that modifying System.in is different across platforms and in order to do what you want, you would need to change the terminal from "line" mode to "character" mode.
Take a look Here.
I am facing a problem in implementing Input method for Virtual Keyboard. Currently I am using robot class for sending input to any application from virtual keyboard. But for that I need to create mapping of key-code and unicode, which is not consistent on different keyboard layout, can I directly pass the UNICODE to any application using Input method without worry about mapping between keycode and unicode.
Any useful link or sample code will be useful.
It is a simple Java program which is always on top of any application and work as onscreen keyboard. Using a mouse while you press any button (key) of the keyboard, the corresponding character will be typed in the application running below. This is working perfectly for English Alphabets. I am facing problem while I am doing for unicode.
find the code snippet below
public static void simulateKeyEvent(char key){
try{
AWTKeyStroke awtKS = AWTKeyStroke.getAWTKeyStroke(key);
int key_code = awtKS.getKeyCode();
System.out.println("key = "+key+" keyCode = "+key_code);
robot.keyPress(key_code);
robot.keyRelease(key_code);
}catch(Exception e){
e.printStackTrace();
}
}
How I sovled it:
//on startup: override the SystemEventQueue
EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
final OwnEventQueue newEventQueue = new OwnEventQueue();
eventQueue.push(newEventQueue);
//because dispatchEvent is protected
public class OwnEventQueue {
private final static OwnEventQueue instance;
static{
instance = new OwnEventQueue();
}
#Override
public void dispatchEvent(AWTEvent event) {
super.dispatchEvent(event);
}
public static OwnEventQueue getInstance() {
return instance;
}
}
//then onpress of keyboard button
Character character = getCharacter();
int[] events = {KeyEvent.KEY_PRESSED, KeyEvent.KEY_RELEASED, KeyEvent.KEY_TYPED};
for (int i = 0; i < events.length; i++) {
KeyEvent pressKeyEvent = new KeyEvent(focusComponent, events[i], System.currentTimeMillis(), 0, 0, character.charValue());
OwnEventQueue.getInstance().dispatchEvent(pressKeyEvent);
}
robotKeystrokeSender.keyPress(KeyEvent.VK_RIGHT);
robotKeystrokeSender.delay(10);
robotKeystrokeSender.keyRelease(KeyEvent.VK_RIGHT);
Is your virtual keyboard used as a device by your OS ?
Or, in other words, have you tried considering it as a "real" keyboard ?
According to Java hardware abstraction, were your virtual keyboard to be considered as a driver, it should simply work like a real keyboard.
EDIT : according to comment, this is not a virtual device, but a Java application, as a consequence, probleme is different.
According to Javadoc, Robot can send key strokes given as int. To create those key strokes from characters, I would recommand you create them using getKeystroke(char) before to transform them into integer values using getKeycode(). This way, you would have integer values associatesd your unicode characters, whichever they are.
EDIT 2 : once again, a modification ;-)
it seems like getKeyStroke(String) "should" handle unicode characters.