Java - 代码编译但无法识别操作

时间:2015-10-14 19:31:49

标签: java binding key action

由于焦点问题,我在Java中的关键监听器遇到了一些麻烦所以我读了很多关于它的内容,许多网站建议使用密钥绑定。 我的代码在下面,我正在尝试将空格键映射到一个动作TestAction。面板对象只是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");
}

}

问题在于虽然它只是没有错误地编译,但是当我按空格键时没有任何反应。

3 个答案:

答案 0 :(得分:1)

我认为你的问题正如William Morrison所说的那样,JPanel没有关注。

添加面板后,尝试拨打requestFocus()。如果您可以发布一个包含少量代码的示例,我们可以为您提供更多帮助。

答案 1 :(得分:1)

感谢所有人的帮助!

你是对的,面板没有聚焦,包含它的框架是。 添加panel.requestFocus();修复它!

答案 2 :(得分:0)

使用您的代码作为基础,这是有效的。

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)" );
        }
    }
}