open application with key pressing - java

I am building this pop up learning new languages application which if user found an unknown word he can simply press any keyboard key (like e.g alt+p) so that the app pops up and allow him to insert the new word
and in order to make the key get listened to from anywhere i coded the following
public class IsKeyPressed extends JFrame implements KeyListener {
public IsKeyPressed() {
this.setExtendedState(MAXIMIZED_BOTH);
this.setUndecorated(true);
this.setBackground(new Color(0, 0, 0, 0));
this.addKeyListener(this);
this.setAlwaysOnTop(true);
this.setVisible(true);
while (true) {
this.toFront();
this.requestFocus();
this.repaint();
}
}
public static void main(String[] args) {
new IsKeyPressed();
}
#Override
public void keyPressed(KeyEvent ke) {
//open the pop up application
}
but it does only work fine if the frame is focused from taskbar
so basically it ّdoesn`t work
any idea how to fix ? thanks!

but it does only work fine if the frame is focused from taskbar so basically it ّdoesn`t work
any idea how to fix ?
Not with core Java, that's for sure. You're asking how to create a general key listener, one that works even if the application doesn't have focus, and this is something core Java GUI libraries can't do on there own, for the very reason that this functionality would require the coder to get close to the OS to make OS-specific calls, and Java was built to be as OS-agnostic as possible.
So possible solutions include
writing your own OS routines in C and meshing them with your Java program using JNI
writing Java OS routines using JNA
Or (my favorite) use an OS specific tool, such as Auto-It for Windows, to capture the key press and revive your program, and then meshing this with your program via streams.

Related

Using IntelliJ for Swing GUI

this is my first post on stack overflow. I just started out trying to learn how to code (big big noob) and stumbled across a problem that seems impossible to fix for me:
My Uni uses Eclipse for Java programming. I started with IntelliJ which I very much prefer by now and I would like to keep using it. In todays lecture, our professor introduced us to Swing GUI. In Eclipse, she uses Window Builder which is not available for IntelliJ. I thought this would for sure not be a problem until she created a new GUI Class (uploaded a pic with all the options available in Eclipse to create a new GUI). She created a "Application Window" and instantly has some lines of code that are able to run an empty Panel which she uses as a basis to add more content (added the code that comes with creating a new "Application Window" in Eclipse). This option is not available in IntelliJ.
Please forgive me my bad English and super beginner, non existing knowledge of Java.
I've tried to get around this for the whole evening and can't seem to find a working solution.
Basically if someone knows how I can get a working GUI window in IntelliJ that I can use as a basis - that would already help a lot.
How creating a new Swing Project looks in Eclipse
public class guiVorlage {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
guiVorlage window = new guiVorlage();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public guiVorlage() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
I really don't want to switch to Eclipse.
Tried:
Copying + Adjusting the code from Eclipse in an IntelliJ GUI
Watched tutorials but the ones that I watched did not achieve the exact same thing as in the lecture
Write the code manually
I need to be able to have a running GUI in IntelliJ that is empty an can be used as a basis to add more content.

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();
}

netbeans setDefaultCloseOperation

I am trying to set the default close operation in NetBeans 8.0.2 (in Ubuntu 14.04 on an older Asus gaming laptop.) My program is very large but uses no JFrame or java.swing components.
I merely need to save some values when the "x" in the lower right corner is clicked (this is one usual way to stop execution of a java program in NetBeans.)
I found suggestions that involved swing & JFrame, but it wasn't clear just where to insert the code:
DefaultApplicationView view = new DefaultApplicationView(this);
javax.swing.JFrame frame = view.getFrame();
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter(){
public void WindowClosing(WindowEvent e){
System.out.println("CLOSING");
}
}
show(view);
I also found a set of instructions that I think I would prefer to use, but the post is old enough that my NetBeans doesn't have the tabs/menu-items referred to:
Set Window to Design Mode by clicking the 'Design' Tab
In the Navigator: Right click the 'JFrame' -> 'Properties'
In the Properties Tab: Set 'defaultCloseOperation' (top of the list) to 'DO_NOTHING'
Select 'Events' Tab
Scroll down to 'windowClosing'
Click on the "..." button on the right of the event to bring up the custom editor
Click 'Add...' and name the handler (i.e. custom function that you want to have execute on click of the 'X', or window close event).
Click 'Ok'
Netbeans now automatically creates the function and takes to you the function body in the source view
Now simply add what you want to do here: eg. dispose(), or system.exit or pintln(), or whatever your heart desires, as long as its JAVA and makes sense to the app.
Then there are a few other possibly relevant posts, but they all explicitly involve JFrame and/or swing. (Am I ignorant of some fact such as "All NetBeans java applications use JFrame", or some such?)
A pared down example of code for what I'm trying to do would be:
public class MyApp{
public static void main(String[] args){
loadMyVariables();
// do some work that changes variables' values
// during this work user clicks the 'x' box to halt execution
// I need then automatically to save the variables' new values
}
// needs to be called by the OS or GUI when execution is halted by user
public static void saveMyVariables{
// here the usual printStream stuff saves some values to a file
System.exit(0);
}
public static void loadMyVariables{
// here the usual Scanner stuff reads some values from a file
}
}
(I need help setting the tags for this, so I'm doing as instructed and asking the community.)
THANKS

java: how to launch two applications from one launcher

I have 2 classes, and each one of them has a launcher for a form that utilizes them:
DateTester uses DateTest class and is launched by dateLauncher
CylinderTest uses Cylinder class and is launched by cylLauncher
each launcher is simply comprised of
Cylinder program = new Cylinder();
respectively. They both launched fine by themselves. What I would like to do is create a launcher window (just a pane with two buttons) that will launch either program when their buttons is clicked. I just moved everything into the same package (although im thinking that I shouldnt have done that now), and now neither will launch from their respective launcher. I was trying to launch them with something like:
public void actionPerformed(ActionEvent ev)
{
if(ev.getSource() == btnCylinder)
{
Cylinder prgCylinder = new Cylinder();
}
else if (ev.getSource() == btnDate)
{
DateTester prgDate = new DateTester();
}
else{}
}
but it doesnt do anything. I also tried threading them, and that didnt work either. Any suggestions? Or is this actually a lot more complicated than it seems?
turns out it was just the action listener not added for the buttons. paulo answered this in a comment, but i need to close this as answered. thanks paulo.

java mouse capture

How do I capture the mouse in a Java application so that all mouse events (even ones that happen if the mouse is moved outside the app window) are seen by the Java app? This is like the Windows SetCapture function.
You don't; the JVM, or more specifically AWT, only generates input events when Windows sends it input events, and the JVM only registers for those events which occur within it's window.
You might be able to pull it off using JNI, but then again you might not - it will depend if you can get your hands on the information required by the underlying API. Since that's likely to be a window handle, you won't have what you need to invoke the API, even from JNI.
You have to hook the mouse at the operating system level. Windows(Swing, AWT, MFC, etc....) are only aware of mouse movements within their bounds. If you need a way to access the current position of the mouse regardless of where the mouse is on the screen, you need to write an Input Hook: Input Hooks. You can then use JNI or read the STDOUT from a win32 console application designed to use the Input Hook to forward mouse events/positions to your Java code. I use the latter method in some of my user interface test cases with success.
I needed to do that too!
I after searching the web I found that its possible to use the moveMouse in java.awt.Robot.
Basically use Robot to move the mouse into center of your frame. If user moves it: check how much and move it back to center.
No additional packets or JNI are needed for this (my demo uses JOGL and vecmath but that's for the graphics). Is it good enough? Try the demo, its here:
http://www.eit.se/hb/misc/java/examples/FirstPersonJavaProtoGame/
If the above solution is not good enough then perhaps lwjgl is what you need:
http://www.lwjgl.org/javadoc/org/lwjgl/input/Mouse.html
/Henrik Björkman
Just use the system-hook library available on gitHub https://github.com/kristian/system-hook
This only apply to windows-based systems but really simple to implement.
Sample usage
import lc.kra.system.keyboard.GlobalKeyboardHook;
import lc.kra.system.keyboard.event.GlobalKeyAdapter;
import lc.kra.system.keyboard.event.GlobalKeyEvent;
public class GlobalKeyboardExample {
private static boolean run = true;
public static void main(String[] args) {
// might throw a UnsatisfiedLinkError if the native library fails to load or a RuntimeException if hooking fails
GlobalKeyboardHook keyboardHook = new GlobalKeyboardHook();
System.out.println("Global keyboard hook successfully started, press [escape] key to shutdown.");
keyboardHook.addKeyListener(new GlobalKeyAdapter() {
#Override public void keyPressed(GlobalKeyEvent event) {
System.out.println(event);
if(event.getVirtualKeyCode()==GlobalKeyEvent.VK_ESCAPE)
run = false;
}
#Override public void keyReleased(GlobalKeyEvent event) {
System.out.println(event); }
});
try {
while(run) Thread.sleep(128);
} catch(InterruptedException e) { /* nothing to do here */ }
finally { keyboardHook.shutdownHook(); }
}
}

Categories

Resources