The default close shortcut (Cmd+q on Mac) doesn't work on this program i coded in java, do you know why?
I am an absolute beginner and would be glad if you helped me!
The code:
public static void main(String[] args) throws IOException, AWTException{
final Robot robot = new Robot();
robot.delay(2000);
while(true)
{
{
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
robot.delay(50);
}
}
}
}
That would be because Java is trying to be as cross-platform (or platform-independent) as it can be. You could make your own closing shortcut, using the Key class explained in your previous questions (specifically: How to cast a keyboard event). However, I don't think you could detect mac-specific keys, unless you dive into JNI (Java Native Interface), but if you are a beginner I wouldn't recommend it just yet.
For example, say you would like the shortcut to be CTRL+Q. Add another field in your Key class:
private boolean ctrlPressed = false;
Then, make a pressing check:
#Override
public void keyPressed(KeyEvent e)
{
//Previous code
if(e.getKeyCode() == KeyEvent.VK_CONTROL)
{
ctrlPressed = true;
}
}
#Override
public void keyReleased(KeyEvent e)
{
//Previous code
if(e.getKeyCode() == KeyEvent.VK_CONTROL)
{
ctrlPressed = false;
}
}
And finally, the Q part:
#Override
public void keyTyped(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_Q && ctrlPressed)
System.exit(0);
}
Related
This question already has an answer here:
Loop doesn't see value changed by other thread without a print statement
(1 answer)
Closed 11 months ago.
I have some problem with my code. I want to implement a keylistener. I have a keyHandler class which takes care about keyinput and a while loop in the main class to check if a certain key is pressed or not. I dont understand the behavior of my code. the strange thing is that every thing works when I put the System.out.println("hello") command in front of my if statement. but when i comment it out my programm doesnt realize that i press the key Im checkin in my if statement. I think i could find a workaround. but i would be very glad to understand this strange behavior. why is this happening. Sorry for my bad english. I hope you guys can help me.
public static void main(String[] args) {
boolean running = true;
JFrame window;
KeyHandler k = new KeyHandler();
window = new JFrame();
window.setVisible(true);
window.addKeyListener(k);
while (running) {
//System.out.println("hello");
if (k.isKeyPressed(KeyEvent.VK_W)) {
System.out.println("--------------------------------------------------------------------------");
}
}
}
//here is the KeyHandler class
public class KeyHandler implements KeyListener {
private boolean[] keysPressed = new boolean[128];
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
keysPressed[e.getKeyCode()] = true;
System.out.println(e.getKeyChar());
System.out.println(keysPressed[e.getKeyCode()]);
}
#Override
public void keyReleased(KeyEvent e) {
keysPressed[e.getKeyCode()] = false;
System.out.println(e.getKeyChar());
System.out.println(keysPressed[e.getKeyCode()]);
}
public boolean isKeyPressed(int keyCode) {
return keysPressed[keyCode];
}
}
The whole purpose of events and event handling is you don't need a loop to listen for events. Simply start your UI, add the listeners to a list, and allow the listeners to handle the processing.
Create a listener
public interface MyListener extends EventListener {
public void doSomething();
}
Now use it. With this code it just spits out some text when W is pressed, but the listeners could be another component or anything that uses the interface. No need for extra loops.
public class Main {
private EventListenerList listenerList = new EventListenerList();
public Main() {
JFrame frame = new JFrame();
addListener(new MyListener() {
#Override
public void doSomething() {
System.out.println("Hello 1");
}
});
addListener(new MyListener() {
#Override
public void doSomething() {
System.out.println("Hello 2");
}
});
frame.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W) {
fireMyEvent();
}
}
});
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void addListener(MyListener listener) {
listenerList.add(MyListener.class, listener);
}
private void fireMyEvent() {
MyListener[] listeners = listenerList.getListeners(MyListener.class);
if (listeners == null) {
return;
}
for (MyListener listener : listeners) {
listener.doSomething();
}
}
public static void main(String [] args) {
new Main();
}
}
Here's a link that might help. I would not check for a key being pressed by that method. You are creating a resource hog, first off: by having
boolean running = true;
you then enter a while loop,
while (running) {
do x;
}
this can create a spin lock on some systems, this is a very bad practice. As user Lei Yang stated it is really not needed especially with the classes we have today and modern GUI's, your creating an endless loop. One this most certainly is a way to slow down a system, two you really can't continue coding past that point as you have no way to exit the loop. Some IDE's also have a check that won't allow your application to start if you have a loop that is infinite, almost all will at least give you a warning. you should at least if you are looking for a certain key and have to implement it that way do:
while (running) {
//System.out.println("hello");
if (k.isKeyPressed(KeyEvent.VK_W) = "e") {
running = false;
}
}
at least that won't be an endless loop.
#Override
public void keyPressed(KeyEvent e) {
if ( e.getKeyChar() == 'x' ) {
Clicking = true;
}
try {
if(Clicking == true)
robot = new Robot();
while (true) {
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.delay(1000);
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
if(e.getKeyChar() == 'b'){
Clicking = false;
}
} } catch(AWTException awtException) {
awtException.printStackTrace();
}
}
I'm trying to make it so whenever I press b the autoclicker stops it works when I press x but doesn't stop after I press b
You are using the mechanism on the core while, I don't say it is bad, although what about assigning it to methods like run_it and stop_it? Or just, perform_the_click (that cud be more simply).
"I'm trying to make it so whenever I press b the autoclicker stops it works when I press x but doesn't stop after I press b".
I seriously don't see it has sense, try using commas, thus it makes it non-understandable for the community.
Please show more about the project, where does the Clicking just came from?
You require another thread to listen to your 'b's click. Because it is running on the current thread it blocks listening to inputs.
An idea of something like this:
if(e.getKeyChar() == 'x' ) {
if(robot == null) {
robot = new Robot(someObjectIWantToBringOver);
Thread thread = new Thread(robot);
thread.start();
}
}
if(e.getKeyChar() == 'b' ) {
if(robot != null) {
robot.stop();
robot = null;
}
}
//In your Robot class
class Robot implements Runnable {
private volatile boolean running = true;
private final Object xyz;
public Robot(Object abc??) {
this.xyz = abc;
}
...
public void run() {
while(running) {
try{
xyz.mousePress(InputEvent.BUTTON1_DOWN_MASK);
Thread.sleep(1000);
xyz.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
}catch(Exception e) {}
}
}
public void stop() {
running = false;
}
}
Looks like a fun project. Have fun!
So I searched Stackoverflow, but couldn't find any actual answer that I got. If there's already an answer to this question, please tell me.
I have a class with a showDescription method. This prints a string variable.
I require this method to be called whenever the "d" key is pressed, in the main method. So, what would the code be to implement the key press/down event?
Do this if you have a swing application:
f.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if ((e.getKeyCode() == KeyEvent.VK_D) && ((e.getModifiers() & KeyEvent.CTRL_MASK) != 0)) {
System.out.println("woot!");
}
}
#Override
public void keyReleased(KeyEvent e) {
}
});
you can read more here and here
If you have a console application then use:
Read Input until control+d
How can I detect the Windows key modifier for KeyEvent? I have add the code:
textField.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
if ((e.getKeyCode() & KeyEvent.VK_ESCAPE) == KeyEvent.VK_ESCAPE) {
textField.setText("");
}
}
});
But the problem is, when I use the Windows zoom and try to exit from it using Win + Escape, if focus is in TextField, its content clears. I've tried filter by e.getModifiersEx(), but it returns 0. The only way I've found is to detect whether Windows pressed or not, is to create boolean field and change it's value when Windows pressed/released.
So, is there any way to get the Windows key pressure state from KeyEvent for ESCAPE released event?
The way I used for myself:
AbstractAction escapeAction = AbstractAction() {
public void actionPerfomed(ActionEvent e) {
setText("");
}
}
textField.addCaretListener(new CaretListener() {
#Override
public void caretUpdate(CaretEvent e) {
if (textField.getText() == null || textField.getText().isEmpty()) {
textField.getActionMap().remove("escape");
textField.getInputMap().remove(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0));
} else {
textField.getActionMap().put("escape", escapeAction);
textField.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), escapeAction);
}
}
});
The title might be a little misleading, didnt know how to put my problem short.
Basically what im doing is im using keyboardlistener to find out which keys are down and according to that im moving my game character.
The problem is, when you click out of the window, while holding down a key my listener doesnt register the keyReleased event.
I tried to fix it by using mouse listener and the mouseExited event, but that doesnt fix it all the time, sometimes it does sometimes it doesnt.
Heres my implementation:
Keyboard:
public void mouseLeftWindow()
{
for(int i =0;i<KEY_COUNT;i++)
{
keys[i] = false;
}
}
#Override
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if(keyCode>=0 && keyCode<KEY_COUNT)
{
keys[keyCode] = true;
}
}
#Override
public void keyReleased(KeyEvent e)
{
int keyCode = e.getKeyCode();
if(keyCode>=0 && keyCode<KEY_COUNT)
{
keys[keyCode] = false;
}
}
where keys[] is a boolean[] describing, which codes are pressed
mouse:
#Override
public void mouseExited(MouseEvent e)
{
mouseMoved(e);
keyboard.mouseLeftWindow();
}
Your program will listen for further key events even when your mouse exited the component. That means you set everything to false on exit but if a key is still pressed it will be set to true immediately again. I think you are looking for a FocusListener instead of a MouseListener.
addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
}
#Override
public void focusLost(FocusEvent e) {
keyboard.mouseLeftWindow();
}
});