Reputation: 147
I had some trouble with key listeners in Java due to focusing issues so I read up about it and many websites advise using key bindings instead. My code is below and I'm trying to map the space key to an action TestAction. The panel object is just an extension of JPanel.
public class Template_Main {
static Boolean quit = false;
public static void main(String[] args) {
Window window = new Window();
while(!quit) {
window.update();
}
System.exit(0);
}
}
.
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.KeyStroke;
public class Window {
public Frame frame;
public Panel panel;
public Window() {
frame = new Frame();
panel = new Panel();
Action pressedAction = new TestAction();
Action releasedAction = new TestAction();
pressedAction.setEnabled(true);
releasedAction.setEnabled(true);
panel.getInputMap().put(KeyStroke.getKeyStroke("SPACE"),"pressed");
panel.getInputMap().put(KeyStroke.getKeyStroke("released SPACE"),"released");
panel.getActionMap().put("pressed",pressedAction);
panel.getActionMap().put("released",releasedAction);
frame.add(panel);
frame.pack();
}
public void update() {
Logic.update();
updateImages();
sleep();
}
public void updateImages() {
panel.removeAll();
for (int i = 0; i < Imgs.array.size(); ++i) {
Img img = Imgs.get(i);
addImage(img.name, img.x, img.y, img.width, img.height);
}
panel.repaint();
}
public void addImage(String name, int x, int y, int width, int height) {
panel.add(newImageLabel(name, x, y, width, height));
}
public static JLabel newImageLabel(String imageName, int x, int y, int width, int height) {
Toolkit toolkit = Toolkit.getDefaultToolkit();
java.net.URL iconUrl = ClassLoader.getSystemResource("resources/"+imageName);
Image image = toolkit.createImage(iconUrl);
JLabel label = new JLabel(new ImageIcon(image));
label.setBounds(x, y, width, height);
return label;
}
static void sleep() {
try {
Thread.sleep(Math.round(10));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
.
import javax.swing.JFrame;
public class Frame extends JFrame {
public Frame() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle(Config.TITLE);
setResizable(Config.RESIZABLE);
setVisible(true);
}
}
.
import java.awt.Dimension;
import javax.swing.JPanel;
public class Panel extends JPanel {
public Panel() {
setPreferredSize(new Dimension(Config.WIDTH,Config.HEIGHT));
setLayout(null);
setBackground(Config.BG_COLOR);
setFocusable(true);
}
}
.
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
public class TestAction extends AbstractAction {
public TestAction() {
}
@Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("ACTION PERFORMED");
}
}
The problem is while is although it compiles just without error, nothing happens when I press the space bar.
Upvotes: 3
Views: 66
Reputation: 2437
Using your code as a base, this works.
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class App extends JFrame
{
public static void main( String args[] )
{
new App();
}
public App()
{
super( "Test App" );
setLocationRelativeTo( null );
setSize( 600, 450 );
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
getContentPane().add( new KeyBindingPane() );
setVisible( true );
}
private class KeyBindingPane extends JPanel
{
public KeyBindingPane()
{
this.getInputMap().put( KeyStroke.getKeyStroke( "SPACE" ), "pressed" );
this.getInputMap().put( KeyStroke.getKeyStroke( "released SPACE" ), "released" );
getActionMap().put( "pressed", new SpaceBarAction() );
getActionMap().put( "released", new SpaceBarAction() );
requestFocus();
}
}
public class SpaceBarAction extends AbstractAction
{
@Override
public void actionPerformed( ActionEvent e )
{
System.out.println( "ACTION PERFORMED (SPACE BAR)" );
}
}
}
Upvotes: 0
Reputation: 147
Thanks to everyone for all your help!
You are right, the panel was not taking focus, the frame containing it was.
Adding panel.requestFocus();
fixed it!
Upvotes: 1
Reputation: 1320
I think your issue is as William Morrison stated in that the JPanel is not taking focus.
Try throwing in a call to requestFocus() when the panel is added. If you could post a small contained code example, we could help you more.
Upvotes: 1