Unresponsive KeyListener for JFrame - java

I'm trying to implement a KeyListener for my JFrame. On the constructor, I'm using this code:
System.out.println("test");
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) { System.out.println( "tester"); }
public void keyReleased(KeyEvent e) { System.out.println("2test2"); }
public void keyTyped(KeyEvent e) { System.out.println("3test3"); }
});
When I run it, the test message comes up in my console. However, when I press a key, I don't get any of the other messages, as if the KeyListener was not even there.
I was thinking that it could be because the focus is not on the JFrame
and so they KeyListener doesn't receive any events. But, I'm pretty sure it is.
Is there something that I am missing?

If you don't want to register a listener on every component,
you could add your own KeyEventDispatcher to the KeyboardFocusManager:
public class MyFrame extends JFrame {
private class MyDispatcher implements KeyEventDispatcher {
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
System.out.println("tester");
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
System.out.println("2test2");
} else if (e.getID() == KeyEvent.KEY_TYPED) {
System.out.println("3test3");
}
return false;
}
}
public MyFrame() {
add(new JTextField());
System.out.println("test");
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(new MyDispatcher());
}
public static void main(String[] args) {
MyFrame f = new MyFrame();
f.pack();
f.setVisible(true);
}
}

You must add your keyListener to every component that you need. Only the component with the focus will send these events. For instance, if you have only one TextBox in your JFrame, that TextBox has the focus. So you must add a KeyListener to this component as well.
The process is the same:
myComponent.addKeyListener(new KeyListener ...);
Note: Some components aren't focusable like JLabel.
For setting them to focusable you need to:
myComponent.setFocusable(true);

InputMaps and ActionMaps were designed to capture the key events for the component, it and all of its sub-components, or the entire window. This is controlled through the parameter in JComponent.getInputMap(). See How to Use Key Bindings for documentation.
The beauty of this design is that one can pick and choose which key strokes are important to monitor and have different actions fired based on those key strokes.
This code will call dispose() on a JFrame when the escape key is hit anywhere in the window. JFrame doesn't derive from JComponent so you have to use another component in the JFrame to create the key binding. The content pane might be such a component.
InputMap inputMap;
ActionMap actionMap;
AbstractAction action;
JComponent component;
inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
actionMap = component.getActionMap();
action = new AbstractAction()
{
#Override
public void actionPerformed(ActionEvent e)
{
dispose();
}
};
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "dispose");
actionMap.put("dispose", action);

I got the same problem until i read that the real problem is about FOCUS the your JFrame has already added Listeners but tour frame is never on Focus because you got a lot of components inside your JFrame that also are focusable so try:
JFrame.setFocusable(true);
Good Luck

KeyListener is low level and applies only to a single component. Despite attempts to make it more usable JFrame creates a number of component components, the most obvious being the content pane. JComboBox UI is also often implemented in a similar manner.
It's worth noting the mouse events work in a strange way slightly different to key events.
For details on what you should do, see my answer on Application wide keyboard shortcut - Java Swing.

Deion (and anyone else asking a similar question), you could use Peter's code above but instead of printing to standard output, you test for the key code PRESSED, RELEASED, or TYPED.
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
} else if (e.getID() == KeyEvent.KEY_TYPED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
}
return false;
}

in order to capture key events of ALL text fields in a JFrame,
one can employ a key event post processor.
Here is a working example, after you add the obvious includes.
public class KeyListenerF1Demo extends JFrame implements KeyEventPostProcessor {
public static final long serialVersionUID = 1L;
public KeyListenerF1Demo() {
setTitle(getClass().getName());
// Define two labels and two text fields all in a row.
setLayout(new FlowLayout());
JLabel label1 = new JLabel("Text1");
label1.setName("Label1");
add(label1);
JTextField text1 = new JTextField(10);
text1.setName("Text1");
add(text1);
JLabel label2 = new JLabel("Text2");
label2.setName("Label2");
add(label2);
JTextField text2 = new JTextField(10);
text2.setName("Text2");
add(text2);
// Register a key event post processor.
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addKeyEventPostProcessor(this);
}
public static void main(String[] args) {
JFrame f = new KeyListenerF1Demo();
f.setName("MyFrame");
f.pack();
f.setVisible(true);
}
#Override
public boolean postProcessKeyEvent(KeyEvent ke) {
// Check for function key F1 pressed.
if (ke.getID() == KeyEvent.KEY_PRESSED
&& ke.getKeyCode() == KeyEvent.VK_F1) {
// Get top level ancestor of focused element.
Component c = ke.getComponent();
while (null != c.getParent())
c = c.getParent();
// Output some help.
System.out.println("Help for " + c.getName() + "."
+ ke.getComponent().getName());
// Tell keyboard focus manager that event has been fully handled.
return true;
}
// Let keyboard focus manager handle the event further.
return false;
}
}

This should help
yourJFrame.setFocusable(true);
yourJFrame.addKeyListener(new java.awt.event.KeyAdapter() {
#Override
public void keyTyped(KeyEvent e) {
System.out.println("you typed a key");
}
#Override
public void keyPressed(KeyEvent e) {
System.out.println("you pressed a key");
}
#Override
public void keyReleased(KeyEvent e) {
System.out.println("you released a key");
}
});

Hmm.. what class is your constructor for? Probably some class extending JFrame? The window focus should be at the window, of course but I don't think that's the problem.
I expanded your code, tried to run it and it worked - the key presses resulted as print output. (run with Ubuntu through Eclipse):
public class MyFrame extends JFrame {
public MyFrame() {
System.out.println("test");
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
System.out.println("tester");
}
public void keyReleased(KeyEvent e) {
System.out.println("2test2");
}
public void keyTyped(KeyEvent e) {
System.out.println("3test3");
}
});
}
public static void main(String[] args) {
MyFrame f = new MyFrame();
f.pack();
f.setVisible(true);
}
}

I have been having the same problem. I followed Bruno's advice to you and found that adding a KeyListener just to the "first" button in the JFrame (ie, on the top left) did the trick. But I agree with you it is kind of an unsettling solution. So I fiddled around and discovered a neater way to fix it. Just add the line
myChildOfJFrame.requestFocusInWindow();
to your main method, after you've created your instance of your subclass of JFrame and set it visible.

lol .... all you have to do is make sure that
addKeyListener(this);
is placed correctly in your code.

You could have custom JComponents set their parent JFrame focusable.
Just add a constructor and pass in the JFrame. Then make a call to setFocusable() in paintComponent.
This way the JFrame will always receive KeyEvents regardless of whether other components are pressed.

Related

Listening for the CAPS key [duplicate]

This question already has answers here:
KeyListener after Button Is Pressed
(2 answers)
Closed 6 years ago.
I have been trying to build a small utility that listens for when the user presses the "Caps Lock" key. The program should start and first display wheter the key is ON or OFF. The program should also listen for any changes, and update the frame accordingly.
Unfortunately, the only part I can get right is in the beginning, when the frame displays if the Caps key is on or off. After that, it gets stuck. Even if I press the key it changes nothing on screen.
The program is also supposed to produce a .beep() sound when the caps key is on, but it only works if I start it with the key on.
Code:
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(400, 400);
JLabel label = new JLabel("CAPS LOCK IS ON!");
JLabel label1 = new JLabel("CAPS LOCK IS OFF!");
boolean check = Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK);
if (check == true) {
frame.repaint();
frame.add(label);
Toolkit.getDefaultToolkit().beep();
} else {
frame.repaint();
frame.add(label1);
}
keyPressed(KeyCode.CAPS);
frame.show();
}
public static void keyPressed(KeyCode e) {
boolean check = Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK);
if (check == true) {
Toolkit.getDefaultToolkit().beep();
}
}
EDIT: If you only want to know if the Caps key is toggled(on):
if (Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK)) {
label.setText("CAPS LOCK IS ON!");
Toolkit.getDefaultToolkit().beep();
} else {
label.setText("CAPS LOCK IS OFF");
}
This way it only beeps when the caps key is toggled and doesnt beep when is not toggled.
If you want to track "Caps Lock" only within your application, you can do something like:
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher()
{
#Override
public boolean dispatchKeyEvent(KeyEvent e)
{
if (KeyEvent.VK_CAPS_LOCK == e.getKeyCode())
{
boolean check = Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK);
// do something here
}
return false;
}
});
You also might need to track focus and update state when your app is re-focused.
However if you want your application to track Caps Lock system-wide as I suspect you do, than unfortunately you are out of luck. There is no way in pure Java to do it as this is a very OS-specific feature. Still for Windows there is a wrapper around C-code https://github.com/kristian/system-hook
As mentioned in other answers, your code isn't registering a KeyListener, so it's simply reading the locking state of the key once.
To capture the state change on CapsLock, You need to watch for the keyPressed (cap lock on) and keyReleased (cap lock off) separately.
Take a look at this example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class CapChecker {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel label = new JLabel();
frame.add(label);
frame.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_CAPS_LOCK && Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK)) {
label.setText("CAPS LOCK IS ON!");
Toolkit.getDefaultToolkit().beep();
} else {
label.setText("" + e.getKeyChar());
}
}
#Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_CAPS_LOCK) {
label.setText("CAPS LOCK IS OFF!");
}
}
});
frame.setVisible(true);
}
});
}
}
After the Frame is shown, your program does nothing. You have to register a KeyListener to the frame:
frame.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
})
In these methods you can react to key presses or releases.

Adding a Key Listener to a JtextArea

I have a JTextArea called input and I am trying to get the string inputValue loaded into it when I press the up arrow key. so far this code does not seem to work and I am unsure as to why. Please help.
input.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
System.out.println("test");
if(e.getKeyCode() == KeyEvent.VK_UP) {
input.setText(inputValue);
System.out.println("up is pressed");
}
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
});
You should take care when using low level listeners like KeyListeners on Swing text components like JTextAreas, since messing with these can cause the text component to misbehave.
Much better is to use a DocumentListener if you're looking for changes to the document or a DocumentFilter if you want to listen for and block or change text entry before it occurs.
If you just want to be notified of keys such as the up arrow, I'd use Key Bindings -- what the JTextArea uses itself to be notified of and react to key presses, and would replace the key binding with the new one. If you do this with care, you can even call the original action tied to the key press in your new Action. For instance:
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class TextAreaTrapUp extends JPanel {
private JTextArea textArea = new JTextArea(20, 40);
public TextAreaTrapUp() {
// get JTextArea's InputMap and ActionMap
int condition = JComponent.WHEN_FOCUSED;
InputMap inputMap = textArea.getInputMap(condition);
ActionMap actionMap = textArea.getActionMap();
// get the up keystroke
KeyStroke upKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0);
String upKey = (String) inputMap.get(upKeyStroke); // get the input map's key for this keystorke
Action originalUpAction = actionMap.get(upKey); // and get the action map's original action for this key
Action newUpAction = new NewUpAction(originalUpAction); // create our new up action passing in the old one
actionMap.put(upKey, newUpAction); // and set this into our ActionMap
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
add(new JScrollPane(textArea));
}
// Action called when up-arrow pressed
private class NewUpAction extends AbstractAction {
private Action originalUpAction; // the original action
public NewUpAction(Action originalUpAction) {
this.originalUpAction = originalUpAction;
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Up Arrow Pressed");
// if you want to move the caret up, then call the original action
// as well
if (originalUpAction != null) {
originalUpAction.actionPerformed(e);
}
}
}
private static void createAndShowGui() {
TextAreaTrapUp mainPanel = new TextAreaTrapUp();
JFrame frame = new JFrame("TextAreaTrapUp");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
you should override void keypressed instead of keytyped
#Override
public void keyPressed(KeyEvent e) {
System.out.println("test");
if(e.getKeyCode() == KeyEvent.VK_UP) {
input.setText(inputValue);
System.out.println("up is pressed");
}
because it's not a caracter

KeyListener not reacting or being detected [JAVA] [duplicate]

I'm trying to implement a KeyListener for my JFrame. On the constructor, I'm using this code:
System.out.println("test");
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) { System.out.println( "tester"); }
public void keyReleased(KeyEvent e) { System.out.println("2test2"); }
public void keyTyped(KeyEvent e) { System.out.println("3test3"); }
});
When I run it, the test message comes up in my console. However, when I press a key, I don't get any of the other messages, as if the KeyListener was not even there.
I was thinking that it could be because the focus is not on the JFrame
and so they KeyListener doesn't receive any events. But, I'm pretty sure it is.
Is there something that I am missing?
If you don't want to register a listener on every component,
you could add your own KeyEventDispatcher to the KeyboardFocusManager:
public class MyFrame extends JFrame {
private class MyDispatcher implements KeyEventDispatcher {
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
System.out.println("tester");
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
System.out.println("2test2");
} else if (e.getID() == KeyEvent.KEY_TYPED) {
System.out.println("3test3");
}
return false;
}
}
public MyFrame() {
add(new JTextField());
System.out.println("test");
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(new MyDispatcher());
}
public static void main(String[] args) {
MyFrame f = new MyFrame();
f.pack();
f.setVisible(true);
}
}
You must add your keyListener to every component that you need. Only the component with the focus will send these events. For instance, if you have only one TextBox in your JFrame, that TextBox has the focus. So you must add a KeyListener to this component as well.
The process is the same:
myComponent.addKeyListener(new KeyListener ...);
Note: Some components aren't focusable like JLabel.
For setting them to focusable you need to:
myComponent.setFocusable(true);
InputMaps and ActionMaps were designed to capture the key events for the component, it and all of its sub-components, or the entire window. This is controlled through the parameter in JComponent.getInputMap(). See How to Use Key Bindings for documentation.
The beauty of this design is that one can pick and choose which key strokes are important to monitor and have different actions fired based on those key strokes.
This code will call dispose() on a JFrame when the escape key is hit anywhere in the window. JFrame doesn't derive from JComponent so you have to use another component in the JFrame to create the key binding. The content pane might be such a component.
InputMap inputMap;
ActionMap actionMap;
AbstractAction action;
JComponent component;
inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
actionMap = component.getActionMap();
action = new AbstractAction()
{
#Override
public void actionPerformed(ActionEvent e)
{
dispose();
}
};
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "dispose");
actionMap.put("dispose", action);
I got the same problem until i read that the real problem is about FOCUS the your JFrame has already added Listeners but tour frame is never on Focus because you got a lot of components inside your JFrame that also are focusable so try:
JFrame.setFocusable(true);
Good Luck
KeyListener is low level and applies only to a single component. Despite attempts to make it more usable JFrame creates a number of component components, the most obvious being the content pane. JComboBox UI is also often implemented in a similar manner.
It's worth noting the mouse events work in a strange way slightly different to key events.
For details on what you should do, see my answer on Application wide keyboard shortcut - Java Swing.
Deion (and anyone else asking a similar question), you could use Peter's code above but instead of printing to standard output, you test for the key code PRESSED, RELEASED, or TYPED.
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
} else if (e.getID() == KeyEvent.KEY_TYPED) {
if (e.getKeyCode() == KeyEvent.VK_F4) {
dispose();
}
}
return false;
}
in order to capture key events of ALL text fields in a JFrame,
one can employ a key event post processor.
Here is a working example, after you add the obvious includes.
public class KeyListenerF1Demo extends JFrame implements KeyEventPostProcessor {
public static final long serialVersionUID = 1L;
public KeyListenerF1Demo() {
setTitle(getClass().getName());
// Define two labels and two text fields all in a row.
setLayout(new FlowLayout());
JLabel label1 = new JLabel("Text1");
label1.setName("Label1");
add(label1);
JTextField text1 = new JTextField(10);
text1.setName("Text1");
add(text1);
JLabel label2 = new JLabel("Text2");
label2.setName("Label2");
add(label2);
JTextField text2 = new JTextField(10);
text2.setName("Text2");
add(text2);
// Register a key event post processor.
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addKeyEventPostProcessor(this);
}
public static void main(String[] args) {
JFrame f = new KeyListenerF1Demo();
f.setName("MyFrame");
f.pack();
f.setVisible(true);
}
#Override
public boolean postProcessKeyEvent(KeyEvent ke) {
// Check for function key F1 pressed.
if (ke.getID() == KeyEvent.KEY_PRESSED
&& ke.getKeyCode() == KeyEvent.VK_F1) {
// Get top level ancestor of focused element.
Component c = ke.getComponent();
while (null != c.getParent())
c = c.getParent();
// Output some help.
System.out.println("Help for " + c.getName() + "."
+ ke.getComponent().getName());
// Tell keyboard focus manager that event has been fully handled.
return true;
}
// Let keyboard focus manager handle the event further.
return false;
}
}
This should help
yourJFrame.setFocusable(true);
yourJFrame.addKeyListener(new java.awt.event.KeyAdapter() {
#Override
public void keyTyped(KeyEvent e) {
System.out.println("you typed a key");
}
#Override
public void keyPressed(KeyEvent e) {
System.out.println("you pressed a key");
}
#Override
public void keyReleased(KeyEvent e) {
System.out.println("you released a key");
}
});
Hmm.. what class is your constructor for? Probably some class extending JFrame? The window focus should be at the window, of course but I don't think that's the problem.
I expanded your code, tried to run it and it worked - the key presses resulted as print output. (run with Ubuntu through Eclipse):
public class MyFrame extends JFrame {
public MyFrame() {
System.out.println("test");
addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
System.out.println("tester");
}
public void keyReleased(KeyEvent e) {
System.out.println("2test2");
}
public void keyTyped(KeyEvent e) {
System.out.println("3test3");
}
});
}
public static void main(String[] args) {
MyFrame f = new MyFrame();
f.pack();
f.setVisible(true);
}
}
I have been having the same problem. I followed Bruno's advice to you and found that adding a KeyListener just to the "first" button in the JFrame (ie, on the top left) did the trick. But I agree with you it is kind of an unsettling solution. So I fiddled around and discovered a neater way to fix it. Just add the line
myChildOfJFrame.requestFocusInWindow();
to your main method, after you've created your instance of your subclass of JFrame and set it visible.
lol .... all you have to do is make sure that
addKeyListener(this);
is placed correctly in your code.
You could have custom JComponents set their parent JFrame focusable.
Just add a constructor and pass in the JFrame. Then make a call to setFocusable() in paintComponent.
This way the JFrame will always receive KeyEvents regardless of whether other components are pressed.

Adding a timer to KeyListener

I extended a JFrame class and have my own model and JPanel extended classes as instance variables. I implemented KeyListener to my JFrame and it works with the arrow keys but my model moves extremely slow around the frame when I hold the keys down. My question is how do I attach the KeyListener methods to a timer or do something to make my model move faster when I hold the keys. Also if it is possible, how can the model move two directions at once, say left and up?
public class GameController extends JFrame implements KeyListener,ActionListener
{
private GamePieces p;
private GamePanel panel;
private Timer timer;
public GameController()
{
super("Balls");
setSize(800, 600);
timer = new Timer(10, this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new BorderLayout());
p = new GamePieces();
panel = new GamePanel();
p.addObserver(panel);
c.add(panel);
addKeyListener(this);
panel.update(p, null);
setResizable(false);
timer.start();
}
public void actionPerformed(ActionEvent e)
{
String actionCommand = e.getActionCommand();
if (e.getSource() == timer)
{
p.checkEat();
p.moveOthers();
panel.update(p, null);
}
}
public void keyTyped(KeyEvent e)
{
int s = 0;
}
public void keyPressed(KeyEvent e)
{
int key = e.getKeyCode();
if (key==38)
{
p.up();
panel.update(p, null);
}
else if (key==40)
{
p.down();
panel.update(p, null);
}
else if (key==39)
{
p.right();
panel.update(p, null);
}
else if (key==37)
{
p.left();
panel.update(p, null);
}
}
public void keyReleased(KeyEvent e)
{
int o = 0;
}
public static void main(String[]args)
{
GameController a = new GameController();
a.setVisible(true);
}
}
You are on right way but it should be a little more sophisticated. Follow MVC pattern. You should have model which remembers where you panel should be - up(), down() methods only update this model. You should have viewer which shows panel at current position. panel.update() belongs to viewer. And then you should have controller which changes position (invoke these up and down, left and right) and invokes viewer when necessary - to show movement or just next frame.
Your KeyListener tells controller to move position in some intervals when key is pressed. And then it tells controller to stop doing so when key is released. See, all parts move smoothly and independently. Keylistener tells controller what to do, controller does - changes model and invokes viewer. Model does nothing - only holds data. Viewer does nothing only shows current data.
P.S. Don't forget thread safety since you will press multiple keys and they will invoke controller multiple times in the same thread.

Java Swing get input

How can I change this code to accept any key (not only F5) and print the key?
component.getRootPane().getInputMap(JRootPane.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0), "F5 Pressed");
component.getRootPane().getActionMap().put("F5 Pressed", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
// Code here
}
});
how can I ("cahnhe") this code to accept any key (not only F5) and print
the key?
sorry this question doesn't make me some sence, in this form
basic is described in tutorial,
component.getRootPane() could be valid only for JFrame, JDialog, JWindow, practically only JFrame has accesible RootPane
otherwise to add Input/ActionMap to the desired JComponent directly
Use KeyboardFocusManager to register a KeyEventDispatcher:
KeboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
#Override
public boolean dispatchKeyEvent(KeyEvent ke) {
if (yourComponent.hasFocus && ke.getID == KeyEvent.KEY_TYPED) {
// Your code here
// Use ke.getKeyChar() to detect which key was pressed.
}
}
}

Categories