【问题标题】:Java Key Bindings output to console on key pressJava键绑定在按键时输出到控制台
【发布时间】:2014-09-19 13:12:14
【问题描述】:

我正在尝试制作一个程序,当按下箭头键时,它会在屏幕上移动一个矩形。目前我正在研究键绑定,在 KeyListeners 被证明不可靠且相当无用之后。在尝试移动矩形之前,我只是尝试按下向上​​箭头键触发System.out.println("Up key pressed!"),只是为了确保我的 KeyBindings 实际工作。问题是,他们不是。我正在关注this 教程,这与我想要实现的有点不同,但仍应教我如何使用键绑定。为什么 KeyBinding 不起作用?

代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;


public class GamePanel extends JPanel implements Runnable{

    boolean isRunning = true;
    int count = 0;
    Thread t;
    static int rectX = 250;
    static int rectY = 250;
    Action upAction;
    Action downAction;
    Action leftAction;
    Action rightAction;

    public GamePanel()
    {
        upAction = new UpAction();
        t = new Thread(this);
        t.run();
        /*downAction = new DownAction();
        leftAction = new LeftAction();
        rightAction = new RightAction();*/
        this.getInputMap().put(KeyStroke.getKeyStroke("UP"), "upMotion");
        this.getActionMap().put("upMotion",upAction);

    }
    public void run()
    {
        loop();
    }
    public void loop()
    {
        if(isRunning)
        {
            Thread t = Thread.currentThread();
            try
            {
            t.sleep(5);
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
            repaint();
        }

    }
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        count += 1;
        g.drawString(Integer.toString(count), 10, 10);
        g.drawRect(rectX, rectY, 50, 50);
        loop();
    }
    static class UpAction extends AbstractAction
    {
        public void actionPerformed(ActionEvent e)
        {
            System.out.println("Up key pressed!");
            rectY++;
        }
    }
}

主要的JFrame代码:

import javax.swing.*;

public class MainFrame{

    JFrame frame = new JFrame("Space Invaders");
    GamePanel gamepanel = new GamePanel();

    public MainFrame()
    {
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.setSize(500,500);
        frame.setLocationRelativeTo(null);
        frame.add(gamepanel);
    }
    public static void main(String[] args)
    {
        new MainFrame();
    }


}

【问题讨论】:

  • 你的主要在哪里?无法运行此代码。
  • @kai 我的主要代码只是创建了一个 JFrame 并将这个类作为 JPanel 添加到其中
  • 那个循环。它将暂停调用构造函数的当前线程,因此您无法在任何地方运行 Panel(除非您从构造函数导出 this)。尝试在新线程中运行loop 方法。
  • 添加你的主代码,这样我就可以运行它了。
  • @kajacx 我已经编辑了我的代码。不,即使在我编辑之前,我仍然看到一个快速增加的数字并且绘制了一个矩形

标签: java swing paintcomponent key-bindings thread-sleep


【解决方案1】:

整个问题是您的面板没有焦点,因此无法接收任何输入事件。按照this的回答后,添加2行即可解决问题:

public GamePanel() {
    ...
    setFocusable(true); //add this anywhere in this constructor 
}

public MainFrame() {
    ...
    frame.add(gamepanel);
    gamepanel.requestFocusInWindow();
    //add this after adding the panel to your frame and making it visible
}

编辑:

另外,你的代码有几个错误:

  • 向上移动应该是y--,因为左上角的坐标为[0,0],x 轴向右,y向下(不像在数学课)
  • 您应该永远paint() 方法中调用 Thread.sleep(),因为该方法必须尽可能快。
  • 您正在使用thread.run()“启动”一个新线程,请改用thread.start(),这将实际启动一个新线程,而不仅仅是在当前线程中调用run 方法。
  • loop方法中的if更改为while,同时从paint方法中删除loop调用以解决前两个错误。

这些不是为了批评你(每个人都从某个时候开始),而是为了帮助你。

【讨论】:

  • 在 mKorbel 建议将 Thread.sleep() 延迟更改为 25 之后,键绑定在没有这个的情况下工作。但是它们不一致
  • 我必须使用public void start(){...} 还是调用run() 来启动线程?
  • 谷歌“java thread run vs start”并选择你想要的任何链接......:3
  • KeyBindings 默认在 API 中实现了 Focus 的设置,那么关于 Focus 的一切都不能回答 OPs 问题
  • 感谢您的帮助。我现在可以在屏幕上移动一个矩形了!! 成就加强
猜你喜欢
  • 2013-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-02
  • 1970-01-01
  • 2016-03-07
相关资源
最近更新 更多