Robot.keypress and Robot.keyrelease acts weird - java

I am trying to control games from my android phone and I have an issue.
If I press any of the wasd keys and I try putting the input into a text editor, there is no problem. Whether it is the browser, notepad or the ide itself, it works.
However, when I tried it in games ( I tried minecraft and urban terror ), nothing happens.
Did anyone have this issue, do you have any idea how to deal with this?
The client code looks like
if(parts[1].equals("FWD") ) { //we send the string "FWD" from the phone when key 'W' is pressed
try{
Robot robo=new Robot();
robo.keyPress(KeyEvent.VK_W);
robo.keyRelease(KeyEvent.VK_W);
}
catch (AWTException e)
{
System.out.println(e);
}
}

Related

How to detect a pressed key globally, in a window without focus in java? [duplicate]

I'm making a small program in Java using the Robot class. The program takes over the mouse. while in the course of debugging if it starts acting in a way that I don't want it's hard to quit the program, since I can't move the mouse over to the terminate button in eclipse, and I can't use hotkeys to hit it because the mouse is constant clicking in another window, giving that window focus instead.
What I'd like to do is just hook up a keylistener so that when I hit q I can quit the program, but the only way I know how to do this involves making a window, and that window needs focus to capture the input. Is there a way to listen for keyboard or mouse input from anywhere, regardless of what has focus?
There is a library that does the hard work for you:
https://github.com/kwhat/jnativehook
This is not a trivial problem and Java doesn't give you a way to do it elegantly. You can use a solution like banjollity suggested but even that won't work all the time if your errant mouse clicks open another fullsized window currently open in your taskbar for example.
The fact is, Java by default gives developers very little control over the OS. This is due to 2 main reasons: security (as citied by java documentation) and the fact that different operating systems handle events completely differently and making one unified model to represent all of these would probably not make a whole lot of sense.
So to answer your question, I imagine what you want is some kind of behaviour for your program where it listens for keypresses globally, not just in your application. Something like this will require that you access the functionality offered by your OS of choice, and to access it in Java you are going to need to do it through a Java Native Interface (JNI) layer.
So what you want to do is:
Implement a program in C that will listen for global keypresses on your OS, if this OS is Windows than look for documentation on windows hooks which is well docuemented by Microsoft and MSDN on the web and other places. If your OS is Linux or Mac OS X then you will need to listen for global keypresses using the X11 development libraries. This can be done on an ubunutu linux distro according to a Howto that I wrote at http://ubuntuforums.org/showthread.php?t=864566
Hook up your C code to your Java code through JNI. This step is actually the easier step. Follow the procedure that I use in my tutorial at http://ubuntuforums.org/showthread.php?t=864566 under both windows and linux as the procedure for hooking up your C code to your Java code will be identical on both OSes.
The important thing to remember is that its much easier to get your JNI code working if you first code and debug your C/C++ code and make sure that it is working. Then integrating it with Java is easy.
Had same problem. In my case, robot just controlled a single Windows App, that was maximized. I placed these lines at top of main loop driving the robot:
Color iconCenterColor = new Color(255,0,0); // if program icon is red
if (iconCenterColor.equals(robot.getPixelColor(10,15)))
throw new IllegalStateException("robot not interacting with the right app.");
To cancel the robot, just alt-tab to another app. Works great for a simple one app driving robot.
Start the program from a command line in a terminal and use Ctrl-C to terminate it.
(As mentioned by #MasterID and shown on JNativeHook's documentation for native keyboard input detection {main GitHub project here}),
This code should be enough to listen to any key without app focus (press and/or release):
>>Remember to add the jnativehook library in your project to be able to use all its utilities.<<
public class yourClass implements NativeKeyListener {//<-- Remember to add the jnativehook library
public void nativeKeyPressed(NativeKeyEvent e) {
System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public void nativeKeyReleased(NativeKeyEvent e) {
System.out.println("Key Released: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public void nativeKeyTyped(NativeKeyEvent e) {
System.out.println("Key Typed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public static void main(String args[]){
//Just put this into your main:
try {
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
System.exit(1);
}
GlobalScreen.addNativeKeyListener(new yourClass());
//Remember to include this^ ^- Your class
}
}
For this particular problem, use the nativeKeyPressed method like this:
public void nativeKeyPressed(NativeKeyEvent e) {
System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
if (e.getKeyCode() == NativeKeyEvent.VC_Q){
System.exit(1);
}
}
Note that JNativeHook by default shows a lot of stuff in your console that you might not want, to change that, just add this right before the try-catch that you used in the main function as shown (this is also going to turn off warning and error messages, more info here):
//(From here)
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.OFF);
logger.setUseParentHandlers(false);
//(To there-^)
try {
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
System.exit(1);
}
Disclaimer: I know this question was solved years ago, I just hope someone finds this a little easier to find/use.
Have your program open a second window which displays underneath your main window but is maximised, then your errant mouse clicks will all be received by the maximised window, and it can receive your keyboard input.
Here's a pure Java way to do it to solve the problem you've described (not the KeyListener problem... the quit test early when using robot problem):
Throughout your test, compare the mouse position with one that your test has recently set it to. If it doesn't match, quit the test. Note: the important part of this code is the testPosition method. Here's code that I used recently:
public void testSomething() throws Exception {
try {
// snip
// you can even extract this into a method "clickAndTest" or something
robot.mouseMove(x2, y2);
click();
testPosition(x2, y2);
// snip
} catch (ExitEarlyException e) {
// handle early exit
}
}
private static void click() throws InterruptedException {
r.mousePress(InputEvent.BUTTON1_DOWN_MASK);
Thread.sleep(30 + rand.nextInt(50));
r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
Thread.sleep(30 + rand.nextInt(50));
}
private static void testPosition(int x2, int y2) throws ExitEarlyException {
Point p = MouseInfo.getPointerInfo().getLocation();
if(p.x != x2 || p.y != y2) throw new ExitEarlyException();
}

How to press a keyboard key without a physical keyboard in selenium

I'm trying to build an automation script that will install a chrome extension.
On my local system (windows 10) all works fine while using Robot class with java, since I have a physical keyboard connected to my computer.
The problem is - when I try to run this automation on a virtual machine(Amazon EC2, windows server), the Robot class is not working because it doesn't detect a physical connection of a keyboard.
Is there any other way to simulate a keyboard stroke without a keyboard attached?
FYI, I have to use the keyboard because google install box is not part of the page and selenium wont recognize it.
I've tried the sendKeys function but it didn't work because it will affect only the webpage itself and not pop outside of the page
I believe you can use java robot functions to mimic the keyboard interactions.
Example:
package org.kodejava.example.awt;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
public class CreatingKeyboardEvent {
public static void main(String[] args) {
try {
Robot robot = new Robot();
// Create a three seconds delay.
robot.delay(3000);
// Generating key press event for writing the QWERTY letters
robot.keyPress(KeyEvent.VK_Q);
robot.keyPress(KeyEvent.VK_W);
robot.keyPress(KeyEvent.VK_E);
robot.keyPress(KeyEvent.VK_R);
robot.keyPress(KeyEvent.VK_T);
robot.keyPress(KeyEvent.VK_Y);
} catch (AWTException e) {
e.printStackTrace();
}
}
}
I don't think you can do this with Selenium, cause it is meant to test webpages, not to automate a human-computer interaction.
If you want to automate a complex scheme like this, you may try a more complete solution, like UiPath :
https://www.uipath.com/
This is a solution meant for automation, so it will give you more tools to achieve your goal. It has a community edition which is free, and an active forum, so you should be able to handle it quickly !

Why one of my JFrame don't open/show on external jar file?

I have a electronic phone book application with MySql, everything works just fine in my Eclipse, BUT... when i export runnable jar file, when i run my program everything works fine except that one of my JFrame dont want to show (but it show only in eclipse. no erorrs no nothing, i dont know what to do) ...i talk about my frame where the user can add data to database.
my code for showing that JFrame is this
if (conectat) {
try {
PaginaAdd frameAdd = new PaginaAdd();
if (VariabileGlobale.pagAdd == "NU") {
VariabileGlobale.pagAdd = "DA";
// sa aiba iconita
try {
frameAdd.setIconImage(
ImageIO.read(getClass().getResourceAsStream("/data-add-icon.png")));
} catch (IOException e) {
e.printStackTrace();
}
// terminare sa aiba iconita
frameAdd.setLocationRelativeTo(null);
frameAdd.setVisible(true);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else
JOptionPane.showMessageDialog(null, "You are not connected to database!", " Electronic Phone Book",
JOptionPane.WARNING_MESSAGE);
}
Please help. I dont understand why in eclipse work and why on exported jar file not working :((
With the help of user "MadProgrammer" i was able to figure and solve my problem.
Also with this i learned how to use a very importand JAVA command console for running my jar files, where is showing everyting in execution of the program. Soo the command that i used to find the problems is this
java -jar myExecutableNameFile.jar
And my problem was this:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(Unknown Source)
at cnbi.AgendaTelefon.Java.GUI.PaginaAdd.<init>(PaginaAdd.java:388)
at cnbi.AgendaTelefon.Java.GUI.PaginaPrincipala$9.actionPerformed(PaginaPrincipala.java:371)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
My solution was to remove a duplicat image (that has similar name with the current menu image who was calling that jframe to be visible). After i deleted the code and inserted the correct one with new image path... everything works perfect now.
I want to thanks once again to you "MadProgrammer" because you saved me. I was searching to solve this for 5 hours until you came :)

Is there a way to get keyboard events without JFrame?

I want to get my program to unhide main window when user presses some shortcut. Is there a way to get the global key events, not only the ones which happened when focus was inside application frame?
This might do what you want. Note that this code is checking for a Ctr-F keystroke. I use this code to open up a find dialog from anything in the application. I'm pretty sure that the app has to have focus though. Something to try at least...
AWTEventListener listener = new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent event) {
try {
KeyEvent evt = (KeyEvent)event;
if(evt.getID() == KeyEvent.KEY_PRESSED && evt.getModifiers() == KeyEvent.CTRL_MASK && evt.getKeyCode() == KeyEvent.VK_F) {
}
}
catch(Exception e) {
e.printStackTrace();
}
}
};
Toolkit.getDefaultToolkit().addAWTEventListener(listener, AWTEvent.KEY_EVENT_MASK);
EDIT: I think I understand what you want. Basically when the app does NOT have focus. If so then you'll probably have to hook into the OS events with a native API (JNI) but that forces you to a specific OS...
This might be useful. I'm not sure if there is one library that will work for Windows/Linux/Mac. For Windows you will need some external library that uses native code to create a keyboard hook. I have no idea how to do it on the other OSes.
A solution to do this by using a JFrame is to set his opacity to 0.0 and to add the Keylistener to it. But the user will see an icon in his shortcut bar...

Control a Windows apps using Java

I would like to know if there is any way I can control a Windows application using Java code. I have already googled it, and found that it can be done using JNI or a library called NewJawin.
I want to control Windows Media Player using Java code, e.g. play, pause, and change songs, but could find no relevant example to get me started so far. Do you guys have any suggestion?
As no one has answered this question, I thought I would.
public void firePlay() {
//CTRL + P
//import java.awt.Robot
//import java.awt.KeyEvent
try {
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_P);
robot.keyRelease(KeyEvent.VK_P);
robot.keyRelease(KeyEvent.VK_CONTROL);
} catch (AWTException ex) {
Logger.getLogger(atest.class.getName()).log(Level.SEVERE, null, ex);
}
}
This would play/pause the video. You can see other shortcuts here(http://windows.microsoft.com/en-AU/windows-vista/Windows-Media-Player-keyboard-shortcuts)

Categories

Resources