I want to be able register a key pressed event that triggers a boolean variable. I've done it in my main class, but now I am trying to put it into classes, and it doesn't seem to be working.
Here is the hero class:
public class Hero extends Main {
private boolean downPressed;
private boolean leftPressed;
private boolean rightPressed;
public void init() {
}
public void paint(Graphics g, int x_pos, int y_pos) {
if (isDownPressed() && isLeftPressed()) {
this.sprite = hero225;
} else if (isDownPressed() && isRightPressed()) {
this.sprite = hero135;
} else if (isUpPressed() && isRightPressed()) {
this.sprite = hero45;
} else if (isUpPressed() && isLeftPressed()) {
this.sprite = hero315;
} else if (isLeftPressed() == true) {
this.sprite = hero270;
} else if (isRightPressed() == true) {
this.sprite = hero90;
} else if (isUpPressed() == true) {
this.sprite = hero;
System.out.println("Succsess");
} else if (isDownPressed() == true) {
this.sprite = hero180;
}
// this.sprite will contain value set on last "movement"
g.drawImage(this.sprite, x_pos, y_pos, this);
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
setLeftPressed(true);
System.out.println("keyPressed");
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
setRightPressed(true);
}
if (e.getKeyCode() == KeyEvent.VK_UP) {
setUpPressed(true);
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
setDownPressed(true);
}
}
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
setLeftPressed(false);
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
setRightPressed(false);
}
if (e.getKeyCode() == KeyEvent.VK_UP) {
setUpPressed(false);
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
setDownPressed(false);
}
}
public void keyTyped(KeyEvent e) {
}
public void mouseClicked(MouseEvent e) {
System.out.println("HIT!");
}
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent e) {
boolean isButtonPressed = true;
}
public void mouseReleased(MouseEvent e) {
boolean isButtonPressed = false;
}
public void setDownPressed(boolean downPressed) {
this.downPressed = downPressed;
}
public boolean isDownPressed() {
return downPressed;
}
public void setLeftPressed(boolean leftPressed) {
this.leftPressed = leftPressed;
}
public boolean isLeftPressed() {
return leftPressed;
}
public void setRightPressed(boolean rightPressed) {
this.rightPressed = rightPressed;
}
public boolean isRightPressed() {
return rightPressed;
}
public void setUpPressed(boolean upPressed) {
this.upPressed = upPressed;
}
public boolean isUpPressed() {
return upPressed;
}
And here is the level class which calls it:
public class Level extends Main {
Hero hero = new Hero();
public void paint(KeyEvent e, Graphics g, double x_pos, double x_pos2) {
repaint();
}
And here is the Paint function in the Main class which calls that:
public void paint(Graphics g) {
Level level = new Level();
level.paint(e, g, x_pos, y_pos);
The problem causing this doesn't seem to be apparent.
You should implement java.awt.event.KeyListener interface in the class(es) that you want to listen for events, in this case Hero, so:
public class Hero extends Main implements java.awt.event.KeyListener
and then register for the events in some method, maybe init or somewhere else using:
addKeyListener(this);
//rest of your code
Or if you want to listen for just some events, you could instead of implement the interface KeyListener, register an adapter:
addKeyListener(new java.awt.KeyAdapter()
{
public void keyPressed(java.awt.KeyEvent e)
{
//handle just this event
}
}
);
//rest of of your code
Sounds like a focus problem: Only the active component will get KeyEvents.
There are several ways to solve this problem, but I found this tutorial covers the ideas quite nicely. But if you want a quick and dirty (dirty? Not sure, easy and simple isn't bad I'd think; just gets a bit bloated for large projects) solution you could just implement a listener for every component and forward the events to some general class that handles it.
Related
public void setUpButtonListeners() {
ActionListener buttonListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
Object o = ae.getSource();
if ((o == slots[3][1]) || (o == slots[3][2])) {
slideDown(slots);
} else if ((o == slots[0][1]) || (o == slots[0][2])) {
slideUp(slots);
} else if ((o == slots[1][3]) || (o == slots[2][3])) {
slideRight(slots);
} else if ((o == slots[1][0]) || (o == slots[2][0])) {
slideLeft(slots);
}
}
};
slots[3][1].addActionListener(buttonListener);
slots[3][2].addActionListener(buttonListener);
slots[0][1].addActionListener(buttonListener);
slots[0][2].addActionListener(buttonListener);
slots[1][3].addActionListener(buttonListener);
slots[2][3].addActionListener(buttonListener);
slots[1][0].addActionListener(buttonListener);
slots[2][0].addActionListener(buttonListener);
}
This the relevant code. I can find a ton of information on how to add keylisteners to specific JComponents but all I want to do is make it so that if(up arrow pressed) then slideUp(slots), instead of having to press JButtons on the screen to call these functions.
Edit:
Fixed, and it was really simple.
Added
frame.setFocusable(true);
frame.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
keyCode = e.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_UP:
slideUp(slots);
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
});
to constructor.
Maybe you should use a custom KeyEventDispatcher to handle the arrow key events, otherwise you will have issues with the components focus.
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher( new ArrowsKeyDispatcher() );
...
class ArrowsKeyDispatcher implements KeyEventDispatcher {
public boolean dispatchKeyEvent(KeyEvent e) {
if(e.getID() == KeyEvent.VK_UP) {
//Do something here when pressing UP ARROWKEY
}
// Do the same for all keys you need to handle globally
...
return false;
}
}
I'm trying to make a game in java, just a simple platformer, but I'm having difficulty when running the code. I can't seem to get any response from key presses. The only thing I can think hasn't been working properly is the keyPressed and keyReleased functions. Below is the relevant code.
public ReflexPanel() {
initBoard();
setFocusable(true);
addKeyListener(this);
Timer timer = new Timer(1000/120, this);
timer.start();
}
private void initBoard() {
loadMenu();
int w = menu.getWidth(this);
int h = menu.getHeight(this);
setPreferredSize(new Dimension(w, h));
}
private void step() {
if(mainMenu){
if(ePressed) {
System.exit(0);
}
if(hPressed) {
loadScores();
repaint();
}
}
}
public void keyTyped(KeyEvent e) {}
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 'e') {
ePressed = true;
}
if (e.getKeyCode() == 'h') {
hPressed = true;
}
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == 'e') {
ePressed = false;
}
if (e.getKeyCode() == 'h') {
hPressed = false;
}
}
#Override
public void actionPerformed(ActionEvent e) {
step();
}
The ePressed and hPressed variables are just booleans set to false by default, and loadScores calls a png file.
You can't do this:
if(e.getKeyCode() == 'e'){
// code logic
}
KeyEvent::getKeyCode doesn't return the char you press on the keyboard. It "returns the integer keyCode associated with the key in this event". When using KeyEvent::getKeyCode you have to use the KeyEvent key constants values predefined in the class. So for example:
if(e.getKeyCode() == KeyEvent.VK_E){
// code logic
}
Or you can use KeyEvent::getKeyChar which "returns the character associated with the key in this event".
You're using getKeyCode() which returns an int value with constants given in KeyEvent class, such as KeyEvent.VK_E.
You're looking to use getKeyChar() which returns 'e' directly.
if (e.getKeyChar() == 'e') { // Now it has an actual chance of working
If I remove the last character of my character ArrayList, the ArrayList is not shorter than before removing a Character. So I can not remove more characters than one.
public static ArrayList<Character> userLineInput;
if (e.getKeyChar() == '\b') {
if (!userLineInput.isEmpty()) {
userLineInput.remove(userLineInput.size()-1);
}
}
Is there a easy way to remove more than one character?
it seems that you need to define something like :
while(keyIsPressed)
if(thePressedKey == '\b'){
removeOneChar();
}
here is a quick solution that may help you :
public class RemoveChar extends KeyAdapter {
public static ArrayList<Character> userLineInput;
private boolean isPressed = false;
private int pressedKey = 0;
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (isPressed)
if (pressedKey == '\b')
removeLastChar();
}
});
#Override
public void keyPressed(KeyEvent e) {
if (!isPressed) {
pressedKey = e.getKeyCode();
t.start();
}
}
#Override
public void keyReleased(KeyEvent e) {
if (isPressed && e.getKeyCode() == pressedKey)
isPressed = false;
}
public void removeLastChar() {
userLineInput.remove(userLineInput.size() - 1);
}
}
I have a JScrollPane subclass with this methods.
private MouseListener currentViewportMouseListener;
private MouseMotionListener currentViewportMouseMotionListener;
private MouseListener currentScrollableMouseListener;
private MouseMotionListener currentScrollableMouseMotionListener;
#Override
public void setViewportMouseListener(MouseListener mouseListener)
{
if (currentViewportMouseListener == mouseListener) return;
viewport.removeMouseListener(currentViewportMouseListener);
viewport.addMouseListener(mouseListener);
currentViewportMouseListener = mouseListener;
}
#Override
public void setViewportMouseMotionListener(MouseMotionListener mouseMotionListener)
{
if (currentViewportMouseMotionListener == mouseMotionListener) return;
viewport.removeMouseMotionListener(currentViewportMouseMotionListener);
viewport.addMouseMotionListener(mouseMotionListener);
currentViewportMouseMotionListener = mouseMotionListener;
}
#Override
public void setScrollableMouseListener(MouseListener mouseListener)
{
if (currentScrollableMouseListener == mouseListener) return;
viewport.getView().removeMouseListener(currentScrollableMouseListener);
viewport.getView().addMouseListener(mouseListener);
currentScrollableMouseListener = mouseListener;
}
#Override
public void setScrollableMouseMotionListener(MouseMotionListener mouseMotionListener)
{
if (currentScrollableMouseMotionListener == mouseMotionListener) return;
viewport.getView().removeMouseMotionListener(currentScrollableMouseMotionListener);
viewport.getView().addMouseMotionListener(mouseMotionListener);
currentScrollableMouseMotionListener = mouseMotionListener;
}
So when I use first pair of methods its ok.
scrollPane.setViewportMouseListener(mouseListener);
scrollPane.setViewportMouseMotionListener(mouseListener);
But if I set viewport and view listeners at the same time, viewport Mouse(Motion)Listener does not catch any events.
scrollPane.setViewportMouseListener(mouseListener);
scrollPane.setViewportMouseMotionListener(mouseListener);
scrollPane.setScrollableMouseListener(scrollableMouseListener);
scrollPane.setScrollableMouseMotionListener(scrollableMouseListener);
And I've checked it out in debugger, both viewport and view listener properties fill correct (different objects).
public void constructorOrMethodThatCreatesViewport()
{
// ...
this.viewport.addMouseListener(mainMouseListener);
this.viewport.addMouseMotionListener(mainMouseListener);
}
private MouseListener currentViewportMouseListener;
private MouseMotionListener currentViewportMouseMotionListener;
private MouseListener currentScrollableMouseListener;
private MouseMotionListener currentScrollableMouseMotionListener;
private final MyMouseListener mainMouseListener = new MyMouseListener();
private class MyMouseListener implements MouseListener, MouseMotionListener
{
private MouseEvent viewportToScrollableEvent(MouseEvent event)
{
Rectangle viewRect = viewport.getViewRect();
MouseEvent r = new MouseEvent((Component) event.getSource(),
event.getID(), event.getWhen(), event.getModifiers(),
event.getX()+viewRect.x, event.getY()+viewRect.y,
Math.abs(event.getX()+viewRect.x),
Math.abs(event.getY()+viewRect.y),
event.getClickCount(), event.isPopupTrigger(),
event.getButton());
return r;
}
public void mouseClicked(MouseEvent e)
{
if (null != currentScrollableMouseListener)
{
currentScrollableMouseListener.mouseClicked(viewportToScrollableEvent(e));
}
if (null != currentViewportMouseListener)
{
currentViewportMouseListener.mouseClicked(e);
}
}
public void mousePressed(MouseEvent e)
{
if (null != currentScrollableMouseListener)
{
currentScrollableMouseListener.mousePressed(viewportToScrollableEvent(e));
}
if (null != currentViewportMouseListener)
{
currentViewportMouseListener.mousePressed(e);
}
}
public void mouseReleased(MouseEvent e)
{
if (null != currentScrollableMouseListener)
{
currentScrollableMouseListener.mouseReleased(viewportToScrollableEvent(e));
}
if (null != currentViewportMouseListener)
{
currentViewportMouseListener.mouseReleased(e);
}
}
public void mouseEntered(MouseEvent e)
{
if (null != currentScrollableMouseListener)
{
currentScrollableMouseListener.mouseEntered(viewportToScrollableEvent(e));
}
if (null != currentViewportMouseListener)
{
currentViewportMouseListener.mouseEntered(e);
}
}
public void mouseExited(MouseEvent e)
{
if (null != currentScrollableMouseListener)
{
currentScrollableMouseListener.mouseExited(viewportToScrollableEvent(e));
}
if (null != currentViewportMouseListener)
{
currentViewportMouseListener.mouseExited(e);
}
}
public void mouseDragged(MouseEvent e)
{
if (null != currentScrollableMouseMotionListener)
{
currentScrollableMouseMotionListener.mouseDragged(viewportToScrollableEvent(e));
}
if (null != currentViewportMouseMotionListener)
{
currentViewportMouseMotionListener.mouseDragged(e);
}
}
public void mouseMoved(MouseEvent e)
{
if (null != currentScrollableMouseMotionListener)
{
currentScrollableMouseMotionListener.mouseMoved(viewportToScrollableEvent(e));
}
if (null != currentViewportMouseMotionListener)
{
currentViewportMouseMotionListener.mouseMoved(e);
}
}
}
How can I get key combination of keys on keyboard E.G. (Ctrl+somekey, Alt+somekey) with Java?
I use KeyEvent listener, MouseEvent listener for all keys on keyboard. I can catch all key event on keyboard by using that listener. But, I cannot catch key combination such as (Ctrl+Alt+Del)....etc.
public void keyPressed(KeyEvent kevt) {
if(kevt.getKeyChar()=='c') {
if(kevt.isAltDown())
//Code if Alt+c pressed
if(kevt.isControlDown())
//Code if Ctrl+c pressed
if(kevt.isShiftDown())
//Code if Shift+c pressed
if(kevt.isAltDown()&&kevt.isControlDown()&&(!kevt.isShiftDown()))
//Code if Alt+Ctrl+c pressed
if(kevt.isAltDown()&&kevt.isShiftDown()&&(!kevt.isControlDown()))
//Code if Alt+Shift+c pressed
if(!(kevt.isAltDown())&&kevt.isControlDown()&&(kevt.isShiftDown()))
//Code if Shift+Ctrl+c pressed
if(kevt.isAltDown()&&kevt.isControlDown()&&kevt.isShiftDown())
//Code if Alt+Ctrl+Shift+c pressed
}
Use the above code, use any character
If you want to check if Alt+C+E is pressed do the following
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.swing.*;
public class Sample implements KeyListener {
private JTextField lbl=new JLabel("Hello");
private JPanel pnl=new JPanel(new BorderLayout());
private JFrame frm=new JFrame ("Sample");
int []arr;int i=0;
public Sample() {
pnl.add("North", lbl);
frm.setContentPane(pnl);
frm.pack();
frm.setVisible(true);
lbl.addKeyListener(this);
arr= new int[3];
public void keyPressed(KeyEvent key) {
arr[i]=key.getKeyCode();
i++;
if((arr[0]==VK_ALT||arr[1]==VK_ALT||arr[2]==VK_ALT)&& (arr[0]==VK_C||arr[1]==VK_C||arr[2]==VK_C)&&(arr[0]==VK_E||arr[1]==VK_E||arr[2]==VK_E)) {
//Code you want
}
}
public void keyReleased(KeyEvent evt) {
arr[i]=null;
}
public void keyTyped(KeyEvent kvt) {
}
}
}
Many of these answers seem very complicated, just thought I'd add my solution.
I wrote a KeyBinder class:
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Hashtable;
public abstract class KeyBinder implements KeyListener
{
private Hashtable<Integer, Boolean> keyMap;
private int[] keyCodes;
public KeyBinder(final int... keyCodes)
{
this.keyMap = new Hashtable<>();
this.keyCodes = keyCodes;
}
#Override
public void keyTyped(final KeyEvent e) { }
#Override
public void keyPressed(final KeyEvent e)
{
getKeyMap().put(e.getKeyCode(), true);
if (getKeysDown())
{
onKeysDown();
}
}
#Override
public void keyReleased(final KeyEvent e)
{
getKeyMap().put(e.getKeyCode(), false);
}
private Hashtable<Integer, Boolean> getKeyMap()
{
return this.keyMap;
}
public boolean getKeysDown()
{
for (final int key : this.keyCodes)
{
if (getKeyMap().containsKey(key))
{
if (!getKeyMap().get(key))
{
return false;
}
} else {
return false;
}
}
return true;
}
public abstract void onKeysDown();
}
And then on my control:
final KeyBinder binder = new KeyBinder(KeyEvent.VK_ALT, KeyEvent.VK_A)
{
#Override
public void onKeysDown()
{
System.out.println("Alt+A");
}
};
startButton.addKeyListener(binder);
Easy :)
#Override
public void keyPressed(KeyEvent evt) {
if (evt.getKeyCode()==KeyEvent.VK_CONTROL) { ctrl = true; }
else if (evt.getKeyCode()==KeyEvent.VK_SHIFT) { shift = true; }
else if (evt.getKeyCode()==KeyEvent.VK_ALT) { alt = true; }
else {
keyHit = KeyEvent.getKeyText( evt.getKeyCode() );
System.out.println("Key Hit is "+keyHit);
}
processLocalKeyEvent(evt);
}
#Override
public void keyReleased(KeyEvent evt) {
if (evt.isControlDown() && keyHit != "") ctrl = true;
if (evt.isAltDown() && keyHit != "") alt = true;
if (evt.isShiftDown() && keyHit != "") shift = true;
if (ctrl) sb.append("Ctrl");
if (shift) sb.append("Shift");
if (alt) sb.append("Alt");
if (!ctrl && !shift && !alt) {
sb.append(keyHit);
} else {
sb.append("_"+keyHit);
}
if (ctrl || shift || alt) {
Thread thread = new Thread();
try {
thread.sleep(300);
rfbProto.capture();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} else if ((ctrl || shift || alt) && keyHit=="") {
rfbProto.capture();
} else if ((!ctrl || !shift || !alt) && keyHit!="") {
rfbProto.capture();
}
ctrl = false;
shift = false;
alt = false;
keyHit = "";
sb = new StringBuffer();
processLocalKeyEvent(evt);
}
private void jTable1KeyReleased(java.awt.event.KeyEvent evt) {
System.out.println(evt.getKeyCode()); //showing code of released button
if(evt.isControlDown() && evt.getKeyCode()==40) // 40 is code for arrow down
{
//if ctrl is pressed and arrow down is released
System.out.println("Released " + evt.getKeyCode());
}
Simple version