I'd like to use a simple java Robot that types a text when I click Ctrl+Q. But this has to be done even if I am focused an another app (eg. a game). My code works fine, but it runs only if my JFrame is in focus.
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Robot robot = null;
try {
robot = new Robot();
} catch (AWTException e) {
e.printStackTrace();
}
robot.mouseMove(350, 150);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
robot.keyPress(KeyEvent.VK_T);
robot.keyRelease(KeyEvent.VK_T);
// Solution for different keyboard layouts (ALT values)
try {
alt(KeyEvent.VK_NUMPAD0, KeyEvent.VK_NUMPAD0, KeyEvent.VK_NUMPAD4, KeyEvent.VK_NUMPAD7);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
robot.keyPress(KeyEvent.VK_Q);
robot.keyRelease(KeyEvent.VK_Q);
}
you should try the jnativehook
example usage
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;
import java.util.logging.*;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
public class Example implements NativeKeyListener
{
public void nativeKeyPressed(NativeKeyEvent e)
{
if(NativeKeyEvent.getKeyText(e.getKeyCode()).equals("A"))
{
Robot bot = new Robot();
bot.keyPress(KeyEvent.VK_A);
}
}
public void nativeKeyReleased(NativeKeyEvent e)
{
}
public void nativeKeyTyped(NativeKeyEvent e)
{
}
public static void main(String[] args)
{
Example ex = new Example();
try
{
GlobalScreen.registerNativeHook();
Logger logger =
Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.OFF);
}
catch(NativeHookException eb)
{
System.out.println(eb.getMessage());
}
GlobalScreen.addNativeKeyListener(ex);
}
}
This code uses native methods of windows but the good thing is, its easily readable by a java programmer and not a c#,c++,c etc programmer.This library of classes will listen to the key pressed on any application(it is a global keyboard listener), if a certain key is press then perform the Robot class methods(e.g. mousePress() etc.).
P.S. the documentation of classes used is in the file of jnativehook that you are going to download
Related
So, I'm fairly new to programming and I like to fiddle with it and one day my friend asked me to make a program where when you click, "ctrl" and "s" would be "pressed". I looked at lots of forums trying to make a functional code but, since I'm new to Java, I only got separate pieces of codes and threw it all together.
My code looks like this:
import java.awt.event.MouseEvent;
import java.awt.*;
import java.awt.event.*;
import java.awt.Robot;
import java.util.Scanner;
public class MyClass {
public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
System.out.println("press any key to exit.");
keyboard.next();
System.exit(0);
}
public void mouseClicked(MouseEvent evt) {
try {
Robot robot = new Robot();
// Simulate a key press
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_S);
robot.keyRelease(KeyEvent.VK_S);
robot.keyRelease(KeyEvent.VK_CONTROL);
} catch (AWTException e) {
}
}
}
Your program has no GUI and, therefore, nothing to invoke your mouse listener. The code within the listener appears correct, all you need to do is search for how to create a basic GUI and add the mouse listener to it so you get the results you want.
The following code may help you to handle Ctrl + S
public class SwingApp1 extends JFrame implements KeyListener {
public SwingApp1() {
setSize(500, 500);
setLocationRelativeTo(null);
setBackground(Color.blue);
addKeyListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
SwingApp1 main = new SwingApp1();
main.setVisible(true);
}
#Override
public void keyTyped(KeyEvent evt) {
}
#Override
public void keyPressed(KeyEvent e) {
System.out.println("Pressed=>" + e.getKeyCode());
if (e.getKeyCode() == 83) {
System.out.println("Pressed Ctrl + S");
} // Ctrl + S
}
#Override
public void keyReleased(KeyEvent e) {
}}
I have been trying to write this autoclicker with java for around 7 hours now. I wrote some of this based on other people's code, some by myself. I used JNativeHook to capture clicks in windows outside of Eclipse/the console.
The idea is this: When you hold left click, the Robot will left click for you with 300 ms in between each click.
The problem, however, is that when I left click, I do not execute the code to make the robot run. When I add the line "test.run();" in the nativeMousePressed listener, YES, it DOES autoclick, but when I release left click, It still runs. The only way to then stop it is to click the stop button on eclipse.
Now, I understand I need to make it run in a new thread so I can still use listeners with it, which I attempted to do with this in my MousePressed listener:
Thread test = new Thread(new Runnable() {
public void run() {
try {
Robot robot = new Robot();
System.out.println("GOT HERE 1");
System.out.println("Got HERE 4");
try {
Thread.sleep(300);
System.out.println("Got HERE 5");
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
// robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
System.out.println("Got HERE 6");
// if ();
} catch (InterruptedException ex) {
}
} catch (AWTException e1) {
}
;
}
});
I already removed my loop because that did not seem to do anything to change it. Can somebody explain to me what is going wrong here?
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputListener;
public class AutoClicker implements NativeMouseInputListener {
public void nativeMouseClicked(NativeMouseEvent e) {
// dont need
}
public void nativeMousePressed(NativeMouseEvent e) {
if (e.getButton() == NativeMouseEvent.BUTTON1) {
System.out.println("Mouse Pressed: " + e.getButton());
run = true;
System.out.println(run);
Thread test = new Thread(new Runnable() {
public void run() {
try {
Robot robot = new Robot();
System.out.println("GOT HERE 1");
System.out.println("Got HERE 4");
try {
Thread.sleep(300);
System.out.println("Got HERE 5");
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
// robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
System.out.println("Got HERE 6");
// if ();
} catch (InterruptedException ex) {
}
} catch (AWTException e1) {
}
;
}
});
}
}
public void nativeMouseReleased(NativeMouseEvent e) {
if (e.getButton() == NativeMouseEvent.BUTTON1) {
System.out.println("Mouse Released: " + e.getButton());
run = false;
System.out.println(run);
}
}
public void nativeMouseMoved(NativeMouseEvent e) {
// dont need
}
public void nativeMouseDragged(NativeMouseEvent e) {
// dont need
}
public void click() {
}
public static boolean run = false;
public static void main(String[] args) {
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);
}
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.WARNING);
// Don't forget to disable the parent handlers.
logger.setUseParentHandlers(false);
// Construct the example object.
AutoClicker clicker = new AutoClicker();
// Add the appropriate listeners.
GlobalScreen.addNativeMouseListener(clicker);
}
}
Each mouse press triggers a click, So:
When you start your first click with a mouse press, it triggers the click after 300ms
which triggers another click and so on..
Basically the program gets stuck in an infinite loop of clicking, which i sometimes call the Clickening.
If i know what you're exactly trying to do, i might provide you with a better answer.
But as i understand your question now, a simple solution would just be, to only trigger the mouse release robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); and not do a mouse press. This will complete the click your started with your press after 300ms.
UPDATE: Per the OP's comment, here is the updated code, which uses alt to trigger clicking instead of the left mouse button.
Alt pressed --> clicking starts
Alt released --> clicking stops
Escape pressed --> program exits
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;
import java.awt.*;
import java.awt.event.InputEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AutoClicker implements NativeKeyListener {
public static void main(String[] args) {
try {
GlobalScreen.registerNativeHook();
} catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.exit(1);
}
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.WARNING);
// Don't forget to disable the parent handlers.
logger.setUseParentHandlers(false);
// Construct the example object.
AutoClicker clicker = new AutoClicker();
// Add the appropriate listeners.
GlobalScreen.addNativeKeyListener(clicker);
}
private void startClicking() {
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
Robot robot = new Robot();
while (isClicking) {
Thread.sleep(300);
System.out.println("Clicked!");
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}
} catch (Exception ignored) {
System.out.println("Couldn't click");
}
}
};
Thread clickingThread = new Thread(runnable);
clickingThread.start();
}
private boolean isClicking = false;
#Override
public void nativeKeyPressed(NativeKeyEvent key) {
// When alt is pressed --> Start clicking
if (key.getKeyCode() == NativeKeyEvent.VC_ALT_L || key.getKeyCode() == NativeKeyEvent.VC_ALT_R) {
if (!isClicking) {
System.out.println("Alt pressed, started clicking!");
isClicking = true;
startClicking();
}
}
// If escape is clicked, exit the program
else if (key.getKeyCode() == NativeKeyEvent.VC_ESCAPE) {
System.out.println("Escape button Pressed.EXITING!");
System.exit(0);
}
}
#Override
public void nativeKeyReleased(NativeKeyEvent key) {
if (key.getKeyCode() == NativeKeyEvent.VC_ALT_L || key.getKeyCode() == NativeKeyEvent.VC_ALT_R) {
// When alt is relesed --> Stop clicking
isClicking = false;
System.out.println("Alt released, stopped clicking!");
}
}
#Override
public void nativeKeyTyped(NativeKeyEvent key) {
}
}
I don't know if I should be replying to this considering it is an old thread but I think I had might've found a way without using ALT or a trigger to enable the auto clicker. I had seen that if you were holding mouse button 1, and 100 ms later, the program programmatically releases mouse button1, then you release your real button 1, it says release twice (assuming you had added a print statement in the pressed method in JNativehook). This can be a signal to turn off the auto clicker when it says mouse button 1 that had been released. Hopefully that makes sense!
I want to have a button that, when clicked, opens the default browser and points to a URI.
I have some code that works in my testing, when run in Netbeans 7.x, but it fails when deployed as a JAR. My Java app runs on Linux only.
Anyone see the problem or know of another solution?
This code is in my main form:
linkBtnTest = new LinkButton(
new URI("http://www.example.com/some-page"),
"Click here for blah blah blah");
linkBtnTest.init();
} catch (Exception ex) {
Logger.log(ex);
}
Accessibility.increaseFontSize(linkBtnTest,
ApplicationContext.get().getFontIncreaseSize());
TestPanel.add(linkBtnTest);
Here's the class. I didn't write this code and I'm open to other suggestions:
package com.example.client;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URI;
import javax.swing.JButton;
public class LinkButton extends JButton
implements ActionListener {
/** The target or href of this link. */
private URI target;
final static private String defaultText = "<HTML>Click the <FONT color=\"#000099\"><U>link</U></FONT>"
+ " to go to the example website.</HTML>";
public LinkButton(URI target, String text) {
super(text);
this.target = target;
//this.setText(text);
this.setToolTipText(target.toString());
}
public LinkButton(URI target) {
this( target, target.toString() );
}
public void init() {
this.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
open(target);
}
class OpenUrlAction implements ActionListener {
#Override public void actionPerformed(ActionEvent e) {
open(target);
}
}
private static void open(URI uri) {
if (Desktop.isDesktopSupported()) {
try {
Desktop.getDesktop().browse(uri);
} catch (IOException e) { /* TODO: error handling */ }
} else { /* TODO: error handling */ }
}
}
}
A friend recently asked me to make a simple Buzzer program and has found a strange "bug" in what I wrote for him.
If a key is pushed and the buzzer is reset rapidly over the course of a few seconds he observes a 2 to 3 second freeze of the program that occurs between the the first key press after the reset and the "buzz" indication. He has the following Java installation:
build 1.7.0_25-b16
However, I do not experience this problem on my computer, with the following Java installation:
$ java -version
java version "1.6.0_51"
Java(TM) SE Runtime Environment (build 1.6.0_51-b11-457-10M4509)
Java HotSpot(TM) 64-Bit Server VM (build 20.51-b01-457, mixed mode)
Upon unfreeze, the program returns the appropriate key (that is, not the last key pressed, but the first one pushed after the reset and before the freeze). This suggests that the problem is not with the listener but with the reaction to the listener.
Any thoughts on what might be causing this phenomenon? Thanks in advance for your help.
Source code:
/**
* Buzzer.java
*
* Buzzer
*/
package org.lexingtonma.lhs.nhb;
import java.awt.Color;
import java.awt.DefaultKeyboardFocusManager;
import java.awt.Font;
import java.awt.KeyEventDispatcher;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* #author Arman D. Bilge
*
*/
public class Buzzer extends JFrame implements KeyListener {
private static final long serialVersionUID = 7492374642744742658L;
private static final String BUZZ_A = "BuzzA.wav";
private static final String BUZZ_B = "BuzzB.wav";
private Clip buzz = null;
private boolean listening = true;
private final JTextField display = new JTextField(3);
private final JButton reset = new JButton("Reset");
{
DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager()
.addKeyEventDispatcher(new KeyEventDispatcher() {
public boolean dispatchKeyEvent(KeyEvent e) {
keyTyped(e);
return false;
}
});
setTitle("Buzzer");
final JPanel panel = new JPanel();
setSize(256, 162);
setDefaultCloseOperation(EXIT_ON_CLOSE);
display.setFont(new Font("Helvetica", Font.BOLD, 64));
display.setForeground(Color.WHITE);
display.setVisible(true);
display.setEditable(false);
display.setHorizontalAlignment(JTextField.CENTER);
panel.add(display);
reset.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
display.setText("");
display.setBackground(Color.WHITE);
listening = true;
reset.setEnabled(false);
}
});
reset.setEnabled(false);
panel.add(reset);
add(panel);
try {
buzz = AudioSystem.getClip();
} catch (LineUnavailableException e) {
JOptionPane.showMessageDialog(this, e.getLocalizedMessage(), "FATAL ERROR", JOptionPane.ERROR_MESSAGE);
}
}
public static final void main(String args[]) {
Buzzer b = new Buzzer();
b.setVisible(true);
}
public void keyPressed(KeyEvent e) {
// Do nothing
}
public void keyReleased(KeyEvent e) {
// Do nothing
}
public void keyTyped(KeyEvent e) {
final char c = e.getKeyChar();
if (listening && Character.isLetterOrDigit(c)) {
buzz.close();
listening = false;
if (Character.isDigit(c)) {
display.setBackground(Color.RED);
try {
buzz.open(AudioSystem.getAudioInputStream(getClass().getResource(BUZZ_A)));
buzz.start();
} catch (Exception ex) {
JOptionPane.showMessageDialog(this, ex.getLocalizedMessage(), "FATAL ERROR", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
} else {
display.setBackground(Color.BLUE);
try {
buzz.open(AudioSystem.getAudioInputStream(getClass().getResource(BUZZ_B)));
buzz.start();
} catch (Exception ex) {
JOptionPane.showMessageDialog(this, ex.getLocalizedMessage(), "FATAL ERROR", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
}
display.setText("" + c);
reset.setEnabled(true);
}
}
}
Jar: https://www.dropbox.com/s/62fl2i97m9hrx9m/Buzzer.jar
It's safer to create a new Clip object every time and discard the old one. Try this method
public static void play(String name) {
try{
AudioInputStream sounds = AudioSystem.getAudioInputStream(Buzzer.class.getResource(name));
final Clip clip = AudioSystem.getClip();
clip.addLineListener(new LineListener() {
public void update(LineEvent e) {
LineEvent.Type type = e.getType();
if(type == type.STOP) clip.close();
}
});
clip.open(sounds);
clip.start();
} catch(Exception e){
e.printStackTrace();
}
}
As was suggested, you could give keybinding a try to see if it helps. This just shows how to do it with the Enter key.
public class Buzzer extends JFrame {
private static final String enter = "ENTER";
public Buzzer() {
// Key bound AbstractAction item
enterAction = new EnterAction();
// Gets the JFrame InputMap and pairs the key to the action
this.getInputMap().put(KeyStroke.getKeyStroke(enter), "doEnterAction");
// This line pairs the AbstractAction enterAction to the action "doEnterAction"
this.getActionMap().put("doEnterAction", enterAction);
}
private class EnterAction extends AbstractAction {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Enter was pressed.");
}
}
}
Actually I can't remember if this will work when applied to a JFrame, you might need to make a JPanel first to apply these to. Just replace 'this' with the panel name.
I've been trying and failing to use the java full screen mode on the primary display of an OSX system. Whatever I've tried I can't seem to get rid of the 'apple' menu bar from the top of the display. I really need to paint over the entire screen. Can anyone tell me how to get rid of the menu?
I've attached an example class which exhibits the problem - on my system the menu is still visible where I would expect to see a completely blank screen.
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
public class FullScreenFrame extends JFrame implements KeyListener {
public FullScreenFrame () {
addKeyListener(this);
setUndecorated(true);
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
if (gd.isFullScreenSupported()) {
try {
gd.setFullScreenWindow(this);
}
finally {
gd.setFullScreenWindow(null);
}
}
else {
System.err.println("Full screen not supported");
}
setVisible(true);
}
public void keyTyped(KeyEvent e) {}
public void keyPressed(KeyEvent e) {}
public void keyReleased(KeyEvent e) {
setVisible(false);
dispose();
}
public static void main (String [] args) {
new FullScreenFrame();
}
}
I think your problem is here:
try {
gd.setFullScreenWindow(this);
}
finally {
gd.setFullScreenWindow(null);
}
finally blocks are always executed, so what happens here is that you window becomes full screen for a brief instant (if that) and then relinquishes the screen immediately.
Also, setVisible(true) is not necessary when you have previously called setFullScreenWindow(this), according to the Javadocs.
So I would change the constructor to this:
public FullScreenFrame() {
addKeyListener(this);
GraphicsDevice gd =
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
if (gd.isFullScreenSupported()) {
setUndecorated(true);
gd.setFullScreenWindow(this);
} else {
System.err.println("Full screen not supported");
setSize(100, 100); // just something to let you see the window
setVisible(true);
}
}
On OS X (10.7 and higher), it is better to use the native fullscreen mode available. You should use:
com.apple.eawt.FullScreenUtilities.setWindowCanFullScreen(window,true);
com.apple.eawt.Application.getApplication().requestToggleFullScreen(window);
where window is the window (JFrame, etc) that you want to take fullscreen
Thats a bit pedantic, the answer is to follow the tutorial completely, which has the essentials and is somewhat more expansive than would fit in a post. The above sample does not work because it is missing a validate(); and some content. I suspect the Java Tutorial will not disappear any time soon. Below is a modified version
package test;
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class FullScreenFrame extends JFrame implements KeyListener {
public FullScreenFrame () {
addKeyListener(this);
setUndecorated(true);
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
if (gd.isFullScreenSupported()) {
try {
this.getContentPane().addKeyListener(this);
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add("Center", new JLabel("Full Screen, back to normal in 10 seconds"));
gd.setFullScreenWindow(this);
validate();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} finally {
gd.setFullScreenWindow(null);
}
} else {
System.err.println("Full screen not supported");
}
}
public void keyTyped(KeyEvent e) {
System.out.println("keyTyped:" + e.getKeyChar() + "source:" + e.getSource() );
}
public void keyPressed(KeyEvent e) {
System.out.println("keyPressed:" + e.getKeyChar() + "source:" + e.getSource() );
}
public void keyReleased(KeyEvent e) {
System.out.println("keyReleased:" + e.getKeyChar() + "source:" + e.getSource() );
setVisible(false);
dispose();
}
public static void main (String [] args) {
new FullScreenFrame();
}
}