I would like to be able to have background input in Java. I set up the keyboard listener the usual way (I think). This code works fine, but whenever the program loses focus, the keys stop updating. The update method is ran 60 times a second and continues to be ran while the frame is out of focus, but the keys don't update (If a key is pressed when the frame loses focus, the program will act as if you are holding it down).
My question: is there a way to allow Java to receive background inputs when the frame is out of focus? I would prefer a solution without external libraries but any will help.
The reason I would like to do this is because my program will have multiple frames and I need to be able to receive input in the main frame even if it is not in focus, including when none of the frames are in focus.
Not sure how helpful it will be but my current code for listening for key events is below.
Here I add the key listener to my main class.
public static Keyboard key;
key = new Keyboard();
addKeyListener(key);
This code is from my Keyboard class
private boolean[] keys = new boolean[120];
public boolean up, down, left, right;
public void update() {
up = keys[KeyEvent.VK_UP] || keys[KeyEvent.VK_W];
down = keys[KeyEvent.VK_DOWN] || keys[KeyEvent.VK_S];
left = keys[KeyEvent.VK_LEFT] || keys[KeyEvent.VK_A];
right = keys[KeyEvent.VK_RIGHT] || keys[KeyEvent.VK_D];
}
public void keyPressed(KeyEvent e) {
keys[e.getKeyCode()] = true;
}
public void keyReleased(KeyEvent e) {
keys[e.getKeyCode()] = false;
}
Related
I have a requirement where need to mask the value entering into jText area at runtime. I am able to achieve this but problem is scenario with backspace. When I press back space sequentially (one by one) then it work while if I kept pressing then its counting the event as one and removing only one character (by considering the key event as one key released).
Here my code snippets is :
public void showPrompt() throws InterruptedException {
sem.acquire();
this.toFront();
this.setAlwaysOnTop(true);
this.setVisible(true);
if(encryptKeystroke == true) {
jTextArea.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
if (e.getExtendedKeyCode() == KeyEvent.VK_BACK_SPACE) {
text = text.substring(0, text.length() - 1);
}
else {
text += String.valueOf(e.getKeyChar());
}
jTextArea.setText(text.replaceAll(".", "*"));
}
});
}
}
Is there any way if I kept pressing the backspace then it should remove all the characters irrespective of considering it one key event ?
As you have said in the comment that the requirements are not exactly like the password and so you won't be using JPasswordField, I would like to give a solution for the question.
Here, the code to detect a backspace key stroke is written inside the keyReleased() method. Now, the keyReleased() method will be called by the keyListener when you will pull your finger up from a key in this case your backspace key. That is why even if you continuously keep pressing the backspace key, it will execute the code only once i.e. only when you release the key.
Now, you wish to remove one character every time backspace is pressed so you can just move your code from the keyReleased() method to the keyPressed() method.
If you move the code inside the keyPressed() method, then the code will be executed at every key stroke even if you continuously keep pressing the backspace key.
I am creating a simple game in which a keypressed event moves a JLabel a certain number of pixels in a JPanel.
It works without any errors and when i hit the right arrow it moves right, and so on. However, as soon as i press a second key it interrupts the original movement.
For example if i was holding down the left key (and the object was moving left) and then i hit the up arrow the object stops moving left. This is (of course) because i am using only one key event for all my key.
This obviously is not an acceptable situation because as soon as i add a second object (for another player) each player will be constantly stopping the other players movement.
So my question is this: How best can i incorporate multiple simultaneous key actions? (preferably without writing dozens of KeyAdapter's and KeyEvent's)
INFO: currently i have a second class which extends a KeyAdapter. This second class includes a KeyPressed function which then uses .getKeyCode(); to find out which key is pressed and act.
EDIT: any suggestions are welcome!
The solution is actually quite simple. When a key pressed event is registered store a variable that records the movement. When a key released event is registered un-store that variable.
This then means that until you release you keys the movement will continue to be registered. The solution also requires a timer in order to loop repeatedly and check if your event is running or not. You could use a delay but a separate thread is the most effective for this type of task.
First you need a global variable that can store your action:
String action = "";
Then you need a key listener to record your input and when you stop inputting:
// create key listener
addKeyListener(new KeyListener()
{
#Override
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
String event = KeyEvent.getKeyText(keyCode);
if (event.equals("A")) {
// DO YOUR EVENT IF THE KEY HAS BEEN PRESSED
action = "A";
}
}
#Override
public void keyTyped(KeyEvent e) {}
#Override
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
String event = KeyEvent.getKeyText(keyCode);
if (event.equals("A")) {
// STOP DOING YOUR EVENT
action = "";
}
}
});
Lastly you will need a timer thread to loop and do your action:
// CREATE A TIMER THREAD
Timer timer = new Timer();
timer.schedule(new TimerTask() {
// this is what happens every time the timer runs
#Override
public void run() {
// check if your action should be preformed
if (action.equals("A")) {
// ... do something
}
}
}, 0, 1000); // 1000 MILLESECONDS = 1 SECOND
// note: you will need to run 'timer.cancel();' at some point to end your timer
Also it is worth looking at these other topics, including this about keylistener is games. And about timer tasks.
Hi I'm new to stackoverflow so bear with me if I make mistakes.
I'm making this Java Simon Says Game for a class project. It works by a random number generator for each sequence#. I show the sequence through doClick() but remove the actionlisteners beforehand and add it afterwards.
The problem is the buttons won't unpress or unarm until all other buttons have been pressed. I've tried using thread.sleep to put a delay between each if...else statements yet it only stays pressed for longer. I've tried updating the gui through repaint(), revalidate(), updateUI() within the try... catch of the thread.sleep but that didn't work either.
I've realized this issue is mainly cosmetic because when I tried implementing setPressed or setArmed it said it wasn't being pressed but it looked pressed.
Here is the code snippet in it's most simplest form without thread.sleep or my previous attempts in comments.
public void sequence2() //This is where the issue happens. The buttons won't unpress until every button has been pressed.
{
level.setText(" Level 2"); //Level indicator
Green.removeActionListener(Listener);
Red.removeActionListener(Listener);
Yellow.removeActionListener(Listener);
Blue.removeActionListener(Listener);
if(sequence1 == 1)
{
Green.doClick(300); //Programmatically clicks the button
}
else if(sequence1 == 2)
{
Red.doClick(300);
}
else if(sequence1 == 3)
{
Yellow.doClick(300);
}
else if(sequence1 == 4)
{
Blue.doClick(300);
}
if(sequence2 == 1)
{
Green.doClick(300);
}
else if(sequence2 == 2)
{
Red.doClick(300);
}
else if(sequence2 == 3)
{
Yellow.doClick(300);
}
else if(sequence2 == 4)
{
Blue.doClick(300);
}
Green.addActionListener(Listener);
Red.addActionListener(Listener);
Yellow.addActionListener(Listener);
Blue.addActionListener(Listener);
}
I'm very new to java so I'm not skilled in multithreading or working on the Event Dispatch Thread for that manner. But if that's the only solution I'll need some more help with that.
I have the full code in a zip file with previous attempts commented out if that will help.
https://drive.google.com/file/d/0Bxg4WleC9jD2VFhoZmZBNjV6Vkk/view?usp=sharing
Invoking doClick() may be an awkward choice for this, as it uses a Timer internally. Instead, use a JToggleButton, which will allow you to control each button's appearance based on its selected state using setSelected(). A complete example is shown in the game Buttons. In the ActionListener of your Swing Timer, select the current button, play its note and increment the sequence index. When all notes have been played, unselect all the buttons.
Addendum: Can you show how you implement the timer?
In outline, given a suitable list of toggle buttons:
private static final int MAX = 4;
List<JToggleButton> buttons = new ArrayList<JToggleButton>(MAX);
private int i;
The timer's listener might look like this:
#Override
public void actionPerformed(ActionEvent e) {
Object src = e.getSource();
JToggleButton b = buttons.get(i);
if (i > MAX) { // reset i and all the buttons
for (JToggleButton b : buttons) {
b.setSelected(false);
}
timer.stop();
i = 0;
} else {
b.setSelected(true);
// play tone i
i++;
}
}
A toggle button's item listener should update the button's appearance as indicated by its state:
#Override
public void itemStateChanged(ItemEvent e) {
JToggleButton b = (JToggleButton) e.getItem();
if (b.isSelected()) {
// change icon, color etc.
} else {
// restore icon, color etc.
}
}
I'm making a small game project in Java. In it you have a character that shoots in the direction of the mouse when "pressed" or "dragged" (you know, in Java's terms). The only problem is that if you stop dragging but you still hold the left mouse button down you stop shooting.
Is there a way to detect if the mouse button is down after a drag?
NOTE: the mouse is not sensed as "pressed" after the drag.
You will get the information when a mouse button is pressed and when it is released again. If you want to know the state in between, you need to use a boolean to store that information.
Example:
final boolean[] buttonStates = new boolean[3];
public void mousePressed(MouseEvent e) {
buttonStates[e.getButton()] = true;
}
public void mouseReleased(MouseEvent e) {
buttonStates[e.getButton()] = false;
}
You would do the same for keyboard input by the way.
I'm trying to code a game similar to Mario in Java and am having problems with making the dude jump while he is running. What the below code ends up doing is, as the user is holding down right and presses the jump button, Mario basically stops running and jumps, so its like the user has let go of right and pressed jump.
public void keyPressed(KeyEvent e) {
// here I keep track of what buttons the user pressed
int keyCode = e.getKeyCode();
if(keyCode == 37)
pressedKeys[0] = true;
else if(keyCode == 39)
pressedKeys[1] = true;
else if(keyCode == 68)
pressedKeys[2] = true;
// after I see what the user has pressed an action is carried out
Thread t = new Thread(this);
t.start();
}
public void performAction()
{
// depending on what the user has pressed a certain action is performed
if(pressedKeys[2]==true)
{
// changes the coordinates of the character itself
// done in another thread so the background can continue
// moving as the user holds down a direction
Thread t = new Thread(mcControl);
t.start();
}
if(pressedKeys[0]==true)
{
changeSprite();
bg.moveImageForward();
}
if(pressedKeys[1]==true)
{
changeSprite();
bg.moveImageBackward();
}
}
public void run() {
performAction();
}
if(keyCode == 37)
Not related to your problem, but NEVER use code like that. Most people don't know what that magic number means.
The better way to do this is to use:
if(keyCode == KeyEvent.VK_???)
Now your code is self documenting.
You want to take a look at How to Write a Key Listener. The KeyEvent object has several methods for learning what modifier keys and mouse buttons were pressed at the time the event was generated.