【问题标题】:KeyPressed() not responding (Regular Java)KeyPressed() 没有响应(常规 Java)
【发布时间】:2017-01-26 13:31:07
【问题描述】:

我正在按照课堂上给出的说明规范编写一个河内塔程序。在继续之前,我想声明我已经搜索了类似的答案并且理解最好使用 KeyBinding。我们需要在课堂上使用 KeyListener。

如果您想了解河内塔的工作原理,请在此处阅读:https://en.wikipedia.org/wiki/Tower_of_Hanoi

我的程序对三个杆中的每一个都使用键 1、2 和 3。你点击这两个动作:第一次点击指定发送杆,第二次点击指定接收杆。

我在构造函数中添加了addKeyListener(this),并编写了一个addNotify() 方法来执行{requestFocus();}。编译不会产生错误。我在 KeyPressed 方法的几个区域内添加了一个 System.out.println("This ran!"); 以查看它是否运行 - 它没有运行。

唯一可能有用的其他信息是我正在使用 getKeyChar() 方法来识别正在按下的键。

如果我缺少正确使用 KeyListener 和 KeyPressed 的某些方面,任何帮助或评论将不胜感激。 谢谢。

这是重新创建示例所需的最少代码:

主类:

class MainFile {
    public static void main(String[] args) {
        new TFrame("Frame");
    }
}

面板类:

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

public class TPanel extends JPanel implements KeyListener {
    boolean towerA;
    boolean towerB;
    boolean towerC;

    public TPanel() {
        super();
        setSize(600, 600);
        addKeyListener(this);
    }

    public void keyTyped(KeyEvent e) {
    }

    public void addNotify() {
        requestFocus();
    }

    public void paint(Graphics g) {
        addNotify();
        if (towerA == true) {
            g.setColor(Color.GREEN);
            g.fillRect(20, getHeight(), 40, 100);
        } else {
            g.setColor(Color.RED);
            g.fillRect(20, 0, 40, 100);
        }
        if (towerB == true) {
            g.setColor(Color.GREEN);
            g.fillRect(100, 0, 40, 100);
        } else {
            g.setColor(Color.RED);
            g.fillRect(100, 0, 40, 100);
        }
        if (towerC == true) {
            g.setColor(Color.GREEN);
            g.fillRect(180, 0, 40, 100);
        } else {
            g.setColor(Color.RED);
            g.fillRect(180, 0, 40, 100);
        }
        repaint();
    }

    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub
        addNotify();
        if (e.getKeyChar() == '1') {
            towerA = true;
        }
        if (e.getKeyChar() == '2') {
            towerB = true;

        }
        if (e.getKeyChar() == '3') {
            towerC = true;

        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }
}

框架类:

    import javax.swing.JFrame;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import java.awt.Dimension;

public class TFrame extends JFrame implements java.awt.event.KeyListener {
    public TFrame(String title) {
        super(title);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        pack();
        addKeyListener(this);

        TPanel p = new TPanel();
        Insets frameInsets = getInsets();

        int frameWidth = p.getWidth() + (frameInsets.left + frameInsets.right);
        int frameHeight = p.getHeight() + (frameInsets.top + frameInsets.bottom);

        setPreferredSize(new Dimension(frameWidth, frameHeight));

        setLayout(null);
        add(p);
        pack();
        setVisible(true);
    }

    @Override
    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub

    }

}

更新:我进行了一些进一步的研究,发现它可能与关注组件有关。我在整个程序中添加了许多焦点和 addNotify() 调用,它似乎没有效果。

【问题讨论】:

  • 您确定要调用 addNotify 方法吗?有时你必须在 requestFocus() 之前加上 setFocusable(true)。或者,根据您的设置,您可能需要 requestFocusInWindow() 代替。如果我没记错的话,那就是 JApplets。
  • 您必须添加代码的相关部分。
  • @Perry Monschau 我确实称它为 - 在paint() 方法和 KeyListener 中只是为了确定。
  • @PM77-1 道歉 - 作为班级政策的一部分,我们不能在互联网上粘贴部分学校代码。我可以尝试重新创建其中的一部分来解决这个问题——我应该添加什么?
  • 添加重现问题所需的最少代码。

标签: java events graphics keylistener towers-of-hanoi


【解决方案1】:

这是一个单一的复制/粘贴、编译、运行是一个 MCVE。问题中看到的代码存在一些问题。在偶然发现问题的根本原因之前,我修复了其中一些(参见代码中的 cmets),因为代码覆盖了 addNotify() 方法。请注意,此时对requestFocus() 的调用无论如何都会失败,因为组件不仅需要可聚焦,而且还需要在屏幕上可见才能正常工作。

这部分留作练习供您实施,但如果您遇到问题,请发布另一个问题与 MCVE。

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

public class TPanel extends JPanel implements KeyListener {

    boolean towerA;
    boolean towerB;
    boolean towerC;

    public TPanel() {
        super();
        setSize(600, 600);
        // for testing
        setBackground(Color.BLACK);
        addKeyListener(this);
        // A component must BE focusable before it can hop to accept the focus.
        setFocusable(true); 
        // create an animation listener
        ActionListener animationListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                repaint();
            }
        };
        // create and start an animation timer
        Timer timer = new Timer(200, animationListener);
        timer.start();
        requestFocus();
    }

    public void keyTyped(KeyEvent e) {
    }

    @Override
    /* I've never bothered to find out what addNotify() method is for.
    Inadvisable to use it to request the focus! 
    public void addNotify() {
        requestFocus();
    } */

    /* For any JComponent, we should override the paintComponent(Graphics)
    method rather than the paint(Graphics) method. */
    public void paintComponent(Graphics g) {
        /* 1st thing should be done in any overridden paint method is to
        call the super method. */
        super.paintComponent(g);
        //addNotify();
        if (towerA == true) {
            g.setColor(Color.GREEN);
            g.fillRect(20, getHeight(), 40, 100);
        } else {
            g.setColor(Color.RED);
            g.fillRect(20, 0, 40, 100);
        }
        if (towerB == true) {
            g.setColor(Color.GREEN);
            g.fillRect(100, 0, 40, 100);
        } else {
            g.setColor(Color.RED);
            g.fillRect(100, 0, 40, 100);
        }
        if (towerC == true) {
            g.setColor(Color.GREEN);
            g.fillRect(180, 0, 40, 100);
        } else {
            g.setColor(Color.RED);
            g.fillRect(180, 0, 40, 100);
        }
        /* As mentioned in comment, this will cause an infinite loop & block
        the EDT! Use a Swing Timer for animation. */
        // repaint(); 
    }

    @Override
    public void keyPressed(KeyEvent e) {
        // for testing
        System.out.println("e: " + e);
        addNotify();
        if (e.getKeyChar() == '1') {
            towerA = true;
        }
        if (e.getKeyChar() == '2') {
            towerB = true;

        }
        if (e.getKeyChar() == '3') {
            towerC = true;

        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    public static void main(String[] args) {
        new TFrame("Frame");
    }
}

class TFrame extends JFrame implements java.awt.event.KeyListener {

    public TFrame(String title) {
        super(title);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        pack();
        addKeyListener(this);

        TPanel p = new TPanel();
        Insets frameInsets = getInsets();

        int frameWidth = p.getWidth() + (frameInsets.left + frameInsets.right);
        int frameHeight = p.getHeight() + (frameInsets.top + frameInsets.bottom);

        setPreferredSize(new Dimension(frameWidth, frameHeight));

        // Java GUIs were designed to work with layouts. Use them! 
        // setLayout(null);
        add(p);
        pack();
        setVisible(true);
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-01-16
  • 2012-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 2016-12-18
相关资源
最近更新 更多