Java jnativehook typing a string not working - java

I'd like to type: "/ammo" when I type ALT+A.
The program runs but it seems like to stop right after the running:
I press alt+A or A and the code is not doing anything at all.
package jnativehook01;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;
public class Example implements NativeKeyListener {
public void nativeKeyPressed(NativeKeyEvent e) {
if (NativeKeyEvent.getKeyText(e.getKeyCode()).equals("A")) {
try {
GlobalScreen.unregisterNativeHook();
Robot bot;
try {
bot = new Robot();
String text = "/ammo";
StringSelection stringSelection = new StringSelection(text);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, stringSelection);
//type: /ammo
bot.keyPress(KeyEvent.VK_T);
bot.keyRelease(KeyEvent.VK_T);
} catch (AWTException e1) {
}
} catch (NativeHookException e1) {
}
}
}
public void nativeKeyReleased(NativeKeyEvent e) {
System.out.println("Key Released: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public void nativeKeyTyped(NativeKeyEvent e) {
System.out.println("Key Typed: " + e.getKeyText(e.getKeyCode()));
}
public static void main(String[] args) {
new Example();
}
}

Ok, now it's working:
package jnativehook01;
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.AWTException;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
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;
try {
String text = "/ammo";
StringSelection stringSelection = new StringSelection(text);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, stringSelection);
bot = new Robot();
for (int i = 0; i < 10; i++) {
//t
bot.keyPress(KeyEvent.VK_T);
bot.delay(100);
bot.keyRelease(KeyEvent.VK_T);
bot.delay(500);
bot.keyPress(KeyEvent.VK_CONTROL);
bot.keyPress(KeyEvent.VK_V);
bot.keyRelease(KeyEvent.VK_V);
bot.keyRelease(KeyEvent.VK_CONTROL);
bot.delay(500);
//Enter
bot.keyPress(KeyEvent.VK_ENTER);
bot.keyRelease(KeyEvent.VK_ENTER);
bot.delay(1000);
bot.keyPress(KeyEvent.VK_ENTER);
bot.keyRelease(KeyEvent.VK_ENTER);
bot.delay(400);
}
} catch (AWTException e1) {
}
}
}
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);
}
}

There are still a few problems with your code.
if (NativeKeyEvent.getKeyText(e.getKeyCode()).equals("A")) {
This is not the correct way to check for the A key. This will check to see if AWT produces the ascii 'A' for that key. These values could be overridden by the JVM at runtime. You should check for the NativeKeyEvent.VK_A constant. You also fail to check for the ALT flag on that key event. Something like the following is more of what you are looking for.
if (e.getKeyCode() == NativeKeyEvent.VC_A && e.getModifiers() & NativeInputEvent.ALT_MASK) {
A note on thread safety. You are relying on AWT inside of the key callback, however, this library does not use AWT to dispatch events by default. You need to take a look at the Thread Safety section of the wiki for Thread Safe examples.
You may choose to replace the Robots class with GlobalScreen.postNativeEvent(...) for convenience, to omit Swing/AWT, but it is not required.
A note on blocking inside of the event listener callback. If you block inside this function, via sleep or other long running process, you may cause a delay in key event delivery by the OS or worse, library removal by some operating systems. This removal is outside the control of the library and controlled by the OS.

Related

JTextPane Line Count Including Icons and Components

I've recently been experimenting with the user of JTextPanes for an upcoming project I'll be working on, there have been various posts online detailing how to go about counting the number of lines within the text pane however the solutions I found all seem to fail when inserting Icons or Components into the text pane's document.
The solution I found that worked for plain text was this one (with the solution implemented of course): BadLocationException when using Utilities.getRowStart On hit of Enter key
However once I try to insert a Component (JLabel) or a plain Icon for that matter, the getRowStart() method from Utilities throws a null pointer exception. What I find unusual about this is the Java Doc states that "...This is represented in the associated document as an attribute of one character of content. ", so I assumed it would treat it as any other character but it seems this is not the case.
I've included a code example to replicate the problem if anyone would like to try it. I have a feeling that it just simply isn't possible, which would be a shame.
import java.awt.Dimension;
import java.awt.Image;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Utilities;
public class Test{
private JFrame frame;
private JTextPane textPane;
private Image img;
private URL imgURL;
public Test(){
frame = new JFrame();
frame.setSize(new Dimension(500,300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
textPane = new JTextPane();
try {
imgURL = new URL("http://www.freeiconspng.com/uploads/floppy-save-icon--23.png");
img = ImageIO.read(imgURL);
JLabel label = new JLabel(new ImageIcon(img.getScaledInstance(10, 10, Image.SCALE_SMOOTH)));
textPane.insertComponent(label);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
frame.getContentPane().add(textPane);
frame.setVisible(true);
}
public JTextPane getTextPane(){
return this.textPane;
}
public int getLineCount(){
int totalCharacters = textPane.getDocument().getLength();
int lineCount = (totalCharacters == 0) ? 1 : 0;
try {
int offset = totalCharacters;
while (offset > 0) {
offset = Utilities.getRowStart(textPane, offset) - 1;
lineCount++;
}
} catch (BadLocationException e) {
e.printStackTrace();
}
return lineCount;
}
public static void main(String[] args){
Test t = new Test();
t.getLineCount();
}
}
The problem was solved after the following comment:
It doesn't throw any exception for me once I wrap the content inside
your main method inside a EventQueue.invokeLater() call. I.e.:
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Test t = new Test();
t.getLineCount();
}
});

execute events read from JSON

I am reading two things from a JSON file:
actionOnPress:"robot.KeyPress(e)"
(robot being a java.awt.robot instance) and
event:"KeyEvent.VK_4"
I want to execute
robot.KeyPress(KeyEvent.VK_4)
what is the easiest way (best without needing to download libraries) to execute this? This code is supposed to also work with robot.mousePress and robot.mouseMove etc.
I already tried different things with ScriptEngine, but none of it seems to work.
Thank you very much, Kamik423
EDIT: should be universal. The user should be able to specify different events like FOR EXAMPLE robot
Ok, solved it myself. Here is the code:
package test;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.swing.JFrame;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class executor extends JFrame {
String import1 = "java.awt.Robot";
String import2 = "java.awt.event.KeyEvent";
String setup1 = "r = new Robot";
String executionType = "r.keyPress(event)";
String event = "KeyEvent.VK_4";
private JTextField textField;
static ScriptEngineManager manager = new ScriptEngineManager();
static ScriptEngine engine = manager.getEngineByName("JavaScript");
public executor() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100,100,100,100);
textField = new JTextField();
textField.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent ev) {
try {
engine.eval("importClass(" + import1 + ")");
engine.eval("importClass(" + import2 + ")");
engine.eval(setup1);
engine.eval(executionType.replaceAll("event", event));
} catch (ScriptException e) {
e.printStackTrace();
}
}
});
getContentPane().add(textField, BorderLayout.CENTER);
textField.setColumns(10);
}
public static void main(String[] args) {
executor ex = new executor();
ex.setVisible(true);
}
}

NetBeans can't find main class

I am trying to create a program using applets in NetBeans and I am having a problem. Whenever I try to run a program it says "Project does not have main class set". I was able to get around this by adding
public static void main (String[] args) but my program doesn't do anything. I tried just a generic program to see if it was my coding and it still didn't work. Do I need to reset my NetBeans or is it a coding error?
Here is the code I got from the Oracle website that doesn't work
import javax.swing.JApplet;
import javax.swing.SwingUtilities;
import javax.swing.JLabel;
public class HelloWorld extends JApplet {
//Called when this applet is loaded into the browser.
public void init() {
//Execute a job on the event-dispatching thread; creating this applet's GUI.
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
JLabel lbl = new JLabel("Hello World");
add(lbl);
}
});
} catch (Exception e) {
System.err.println("createGUI didn't complete successfully");
}
}
}
This is the code for my program:
package robot;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.JApplet;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import java.lang.Object;
public class Robot extends JApplet {
private Rectangle rect;
public void init(){
rect = new Rectangle (0, 0, 20,20);
this.addKeyListener((KeyListener) this);
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.white);
g.fillRect(0,0,500,500);
{
this.setSize(355, 355);
}
Graphics2D g1 = (Graphics2D) g;
g1.setColor(Color.black);
g1.fill(rect);
}
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode()== KeyEvent.VK_UP) {
rect.setLocation ( rect.x,rect.y=+20 );
repaint();
}
if (e.getKeyCode()== KeyEvent.VK_DOWN) {
rect.setLocation ( rect.x,rect.y=-20 );
repaint();
}
if (e.getKeyCode()== KeyEvent.VK_RIGHT) {
rect.setLocation ( rect.x =+20, rect.y );
repaint();
}
if (e.getKeyCode()== KeyEvent.VK_LEFT) {
rect.setLocation ( rect.x =-20,rect.y);
repaint();
}
}
}
I was able to run the program if I right clicked in my code then hit "Run Project" but whenever I try and use the run project button it doesn't work.
The second way used to run it simply isn't valid for an applet. That is for an application.
You can set main class by left click on project -> run and select main class:

How to display the information in a browser via Java Applet?

I want to display information about the musical composition in the browser via Java applet. I use the library beaglebuddy_mp3.jar for id3 tags. A folder with files looks like this:
applet
- index.html
- FirstApplet.class
- beaglebuddy_mp3.jar
In index.html I connect an applet:
<applet code="FirstApplet.class" archive="beaglebuddy_mp3.jar" width="500" height="500"></applet>
FirstApplet.class contains the following code:
import java.applet.Applet;
import java.awt.Graphics;
import java.io.File;
import java.io.IOException;
import com.beaglebuddy.mp3.MP3;
public class FirstApplet extends Applet{
public void paint(Graphics g){
try {
MP3 mp3 = new MP3("D:\\Music\\abc.mp3");
g.drawString(mp3.getBand() +" "+mp3.getTitle(), 20, 20);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
After starting the index.html file dialog box appears with a warning stating that I run the application at your own risk. Then I click "Run", instantly appears and disappears gray square. On that nothing is displayed.
Try the following:
import javax.swing.JApplet;
import javax.swing.SwingUtilities;
import javax.swing.JLabel;
import java.io.File;
import java.io.IOException;
import com.beaglebuddy.mp3.MP3;
public class FirstApplet extends JApplet {
public void init() {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
MP3 mp3 = new MP3("D:\\Music\\abc.mp3");
JLabel label = new JLabel(mp3.getBand() +" "+mp3.getTitle());
add(label);
}
});
} catch (Exception e) {
System.err.println("createGUI didn't complete successfully");
}
}
}
And secondly you have to sign your applet code with an official certificate to be able to run it in your web browser.

I am unable to see the components inside my frame

Hi I'm coding an alarm application.
I have a snooze class which gets called when the alarm sounds. It used to work fine before using JMF.But after using JMF I see only the outer frame of my snooze UI.
I tried starting a new thread for the class but got the same result. I'm pasting here code of the classes in which I think the problem is in.
Please help me solve the problem.
*IsTime class. Which checks whether it is the time to sound alarm. *
package alarm;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class IsTime {
int hrs;
int min;
int sec;
GregorianCalendar clk=new GregorianCalendar();
Calendar gtl= Calendar.getInstance();
mp3 mix=new mp3();
public void makeReady(int h,int m,int s,String ampm){
Calendar c1=Calendar.getInstance();
c1.set(Calendar.HOUR_OF_DAY,h);
c1.set(Calendar.MINUTE, m);
c1.set(Calendar.SECOND,s);
if("PM".equals(ampm)){
c1.set(Calendar.AM_PM, Calendar.PM);
if(Calendar.getInstance().get(Calendar.AM_PM)==Calendar.PM){
System.out.println("now is pm");
if(c1.after(Calendar.getInstance())){
check(c1);
}
c1.set(Calendar.DAY_OF_YEAR,c1.get(Calendar.DAY_OF_YEAR)+1);
check(c1);
}
}
if(Calendar.getInstance().get(Calendar.AM_PM)==Calendar.AM){
System.out.println("now is am");
if(c1.after(Calendar.getInstance())){
check(c1);
}
c1.set(Calendar.DAY_OF_YEAR,c1.get(Calendar.DAY_OF_YEAR)+1);
check(c1);
}
if(Calendar.getInstance().get(Calendar.AM_PM)==Calendar.PM){
c1.set(Calendar.DAY_OF_YEAR,c1.get(Calendar.DAY_OF_YEAR)+1);
check(c1);
}
}
public void check(Calendar ch){
System.out.println("got to check");
System.out.println(Calendar.getInstance().get(Calendar.HOUR_OF_DAY));
System.out.println(ch.get(Calendar.HOUR_OF_DAY));
while(!(Calendar.getInstance().after(ch))){
}
Snooze snz=new Snooze();
snz.start();
mix.start();
}
public void makeReady(int mis){
Calendar sz=Calendar.getInstance();
sz.set(Calendar.SECOND, 0);
sz.set(Calendar.MINUTE, Calendar.getInstance().get(Calendar.MINUTE)+mis);
check(sz);
}
}
*Media class which plays song when it is time *
package alarm;
import java.awt.Button;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.media.*;
import java.io.*;
import java.net.URL;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
class mp3 extends Thread
{
private URL url;
private MediaLocator mediaLocator;
private Player playMP3;
static String mp3;
static String mp4;
public mp3()
{
try{
System.out.println(System.getProperty("os.name"));
System.out.println("before"+mp3);
if(System.getProperty("os.name").equals("Linux")){
mp4="file://".concat(mp3);
}
else{
mp4="file:///".concat(mp3);
}
System.out.println(mp4);
this.url = new URL(mp4);
}catch(java.net.MalformedURLException e)
{System.out.println(e.getMessage());}
}
public void run()
{
try{
System.out.println(url);
mediaLocator = new MediaLocator(url);
playMP3 = Manager.createPlayer(mediaLocator);
}catch(java.io.IOException e)
{System.out.println(e.getMessage());
}catch(javax.media.NoPlayerException e)
{System.out.println(e.getMessage());}
playMP3.addControllerListener(new ControllerListener()
{
public void controllerUpdate(ControllerEvent e)
{
if (e instanceof EndOfMediaEvent)
{
playMP3.stop();
playMP3.close();
}
}
}
);
playMP3.realize();
playMP3.start();
}
}
*Snooze class where the real problem is *
package alarm;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Snooze extends Thread implements ActionListener{
JFrame sozef=new JFrame("Snooze");
JLabel tl=new JLabel("After");
JLabel ml=new JLabel("mins");
JComboBox tiec=new JComboBox();
JButton soo=new JButton("Snooze");
JButton stp=new JButton("Stop");
mp3 mi=new mp3();
Snooze sz;
public void run(){
sozef.setSize(500,700);
sozef.setLayout(null);
tl.setBounds(50,50,50,50);
tiec.setBounds(50,90,50,30);
ml.setBounds(120,90,50,50);
soo.setBounds(50,130,90,30);
stp.setBounds(50, 170, 90, 30);
JcAdd(tiec);
sozef.add(tl);
sozef.add(tiec);
sozef.add(ml);
sozef.add(soo);
sozef.add(stp);
soo.addActionListener(this);
sozef.setVisible(true);
sozef.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void JcAdd(JComboBox jc){
for(int i=0;i<=10;i++)
jc.addItem(Integer.toString(i));
}
public void actionPerformed(ActionEvent arg0) {
if(arg0.getSource()==soo){
int ma=Integer.parseInt(tiec.getSelectedItem().toString());
mi.stop();
IsTime sz=new IsTime();
sz.makeReady(ma);
}
mi.stop();
}
} ![this is the frame I see when the snooze is being called][1]
This is not the correct way to implement a delay:
while(!(Calendar.getInstance().after(ch))){
}
In fact, it's going to cause serious problems.
Try calculating the number of milliseconds between your target date and the current time, and passing that value to Thread.sleep. Your computer's case fans will thank you. And it may very well be the case that your busy loop is starving the AWT event thread, thus preventing your frame from showing.

Categories