KeyPressed() 没有响应(常规 Java)
KeyPressed() not responding (Regular Java)
我正在按照 class 中给出的说明规范编写汉诺塔程序。在继续之前,我想声明我已经搜索过类似的答案并理解使用 KeyBinding 更可取。我们需要在 class.
中使用 KeyListener
如果您想了解汉诺塔的工作原理,请阅读此处:https://en.wikipedia.org/wiki/Tower_of_Hanoi
我的程序对三个杆中的每一个都使用键 1、2 和 3。你点击这些两次做一个动作:第一次点击指定发送杆,第二次点击指定接收杆。
我在我的构造函数中添加了 addKeyListener(this)
,同时编写了一个执行 {requestFocus();}
的 addNotify()
方法。编译不会产生错误。我在 KeyPressed 方法的几个区域中添加了一个 System.out.println("This ran!");
以查看它是否运行 - 它没有运行。
唯一可能有用的其他信息是我正在使用 getKeyChar() 方法来识别正在按下的键。
如果我遗漏了正确使用 KeyListener 和 KeyPressed 的某些方面,请提供任何帮助或评论,我们将不胜感激。
谢谢。
这是重新创建示例所需的最少代码:
主要Class:
class MainFile {
public static void main(String[] args) {
new TFrame("Frame");
}
}
面板Class:
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
}
}
帧数Class:
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() 调用,但似乎没有效果。
这是一个单一的 copy/paste,编译,运行 是一个 MCVE。问题中看到的代码存在一些问题。在发现问题的根本原因之前,我修复了其中的一些问题(请参阅代码中的注释),因为代码覆盖了 addNotify()
方法。请注意,此时对 requestFocus()
的调用在任何情况下都会失败,因为组件不仅需要可聚焦,而且还需要在屏幕上可见才能正常工作。
那部分留作练习供您实施,但如果您遇到问题,请 post 使用 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) {
}
}
我正在按照 class 中给出的说明规范编写汉诺塔程序。在继续之前,我想声明我已经搜索过类似的答案并理解使用 KeyBinding 更可取。我们需要在 class.
中使用 KeyListener如果您想了解汉诺塔的工作原理,请阅读此处:https://en.wikipedia.org/wiki/Tower_of_Hanoi
我的程序对三个杆中的每一个都使用键 1、2 和 3。你点击这些两次做一个动作:第一次点击指定发送杆,第二次点击指定接收杆。
我在我的构造函数中添加了 addKeyListener(this)
,同时编写了一个执行 {requestFocus();}
的 addNotify()
方法。编译不会产生错误。我在 KeyPressed 方法的几个区域中添加了一个 System.out.println("This ran!");
以查看它是否运行 - 它没有运行。
唯一可能有用的其他信息是我正在使用 getKeyChar() 方法来识别正在按下的键。
如果我遗漏了正确使用 KeyListener 和 KeyPressed 的某些方面,请提供任何帮助或评论,我们将不胜感激。 谢谢。
这是重新创建示例所需的最少代码:
主要Class:
class MainFile {
public static void main(String[] args) {
new TFrame("Frame");
}
}
面板Class:
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
}
}
帧数Class:
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() 调用,但似乎没有效果。
这是一个单一的 copy/paste,编译,运行 是一个 MCVE。问题中看到的代码存在一些问题。在发现问题的根本原因之前,我修复了其中的一些问题(请参阅代码中的注释),因为代码覆盖了 addNotify()
方法。请注意,此时对 requestFocus()
的调用在任何情况下都会失败,因为组件不仅需要可聚焦,而且还需要在屏幕上可见才能正常工作。
那部分留作练习供您实施,但如果您遇到问题,请 post 使用 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) {
}
}