如何将KeyListener与JFrame一起使用?

所以,我试图使用KeyEventKeyListener )进行矩形移动,每当我尝试按键时,矩形都不会移动。

绘制矩形,但每当我按下right键时,都没有任何反应。 我有两个类,一个是带有keyEvents和框架的主类,另一个是绘制矩形并保存移动矩形的函数。

这是我的代码:

 import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; public class mainFrame extends JFrame implements KeyListener{ mainDraw Draw = new mainDraw(); public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if(key == KeyEvent.VK_D){ Draw.moveRight(); } } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) {} public mainFrame() { addKeyListener(this); setFocusable(true); setFocusTraversalKeysEnabled(false); } public static void main(String[] args) { mainFrame M1 = new mainFrame(); mainDraw Draw = new mainDraw(); JFrame frame = new JFrame("Square Move Practice"); //frame frame.setVisible(true); frame.setResizable(false); frame.setSize(600, 600); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(Draw); } } 

现在是第二节课:

 import java.awt.Color; import java.awt.Graphics; import javax.swing.JComponent; public class mainDraw extends JComponent{ public int x = 50; public int y = 50; public void paint(Graphics g){ g.drawRect(x, y, 50, 50); g.fillRect(x, y, 50, 50); g.setColor(Color.BLACK); } public void moveRight() { x = x + 5; y = y + 0; repaint(); } } 

请告诉我如何移动矩形。 提前致谢!

矩形没有移动,因为您没有正确使用JFrame 。 您必须将frame分配给new mainFrame()而不是忽略实例化的mainFrame对象。

@MadProgrammer指出,还有其他几个问题。

以下是修复某些问题的代码:

mainFrame.java

 import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; public class mainFrame extends JFrame implements KeyListener{ private mainDraw draw; public void keyPressed(KeyEvent e) { System.out.println("keyPressed"); } public void keyReleased(KeyEvent e) { if(e.getKeyCode()== KeyEvent.VK_RIGHT) draw.moveRight(); else if(e.getKeyCode()== KeyEvent.VK_LEFT) draw.moveLeft(); else if(e.getKeyCode()== KeyEvent.VK_DOWN) draw.moveDown(); else if(e.getKeyCode()== KeyEvent.VK_UP) draw.moveUp(); } public void keyTyped(KeyEvent e) { System.out.println("keyTyped"); } public mainFrame(){ this.draw=new mainDraw(); addKeyListener(this); setFocusable(true); setFocusTraversalKeysEnabled(false); } public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { mainFrame frame = new mainFrame(); frame.setTitle("Square Move Practice"); frame.setResizable(false); frame.setSize(600, 600); frame.setMinimumSize(new Dimension(600, 600)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(frame.draw); frame.pack(); frame.setVisible(true); } }); } } 

mainDraw.java

 import java.awt.Color; import java.awt.Graphics; import javax.swing.JComponent; public class mainDraw extends JComponent { public int x = 50; public int y = 50; public void paintComponent(Graphics g) { super.paintComponent(g); g.drawRect(x, y, 50, 50); g.fillRect(x, y, 50, 50); g.setColor(Color.BLACK); } public void moveRight() { x = x + 5; repaint(); } public void moveLeft() { x = x - 5; repaint(); } public void moveDown() { y = y + 5; repaint(); } public void moveUp() { y = y - 5; repaint(); } } 

顺便说一句,使用SwingUtilities来放置gui更新代码,因为swing对象不是线程安全的。

至少有三个问题……

首先…

您的mainFrame类是从JFrame extends ,但是在您的main方法中,您可以通过创建自己的JFrame来创建它的实例并忽略它。

KeyListener已注册到mainFrame的实例,这意味着它已被忽略。

你应该摆脱extends JFrame因为它只是混淆了这个问题

其次…

KeyListener只会在注册的组件可对焦并且具有直接焦点时响应键事件,这使得它不可靠。

相反,您应该使用“ 关键点绑定”API和“ Draw面板,这将允许您解决焦点问题。

第三…

你已经打破了油漆链,这意味着当矩形移动时,之前绘制的内容仍将保留。

你应该避免重写paint ,而是使用paintComponent 。 这有很多原因,但一般来说,它在后台绘制,被称为子组件的更新。

最后,确保在执行任何其他super.paintComponent之前调用super.paintComponent ,以确保为绘制准备Graphics上下文

有关更多详细信息,请参阅执行自定义绘画

您应该在mainDraw类中添加侦听器,而不是mainFrame。

在Frames和Windows中处理键和鼠标事件是一种很好的做法。

O /

我试图将快捷方式监听器实现到整个框架并且没有成功,最后找到了一种方法。 如果要在将焦点设置到另一个组件时设置侦听器,则必须将侦听器添加到所有组件。

这是我的代码,

在构造函数中调用它:

 setShortcutListener(this); // this = JFrame when you call in in constructor 

方法setShortcutListener(JFrame框架):

 private void setShortcutListener(JFrame frame) { List comp_list = Common.getAllComponents(frame); for (Component component : comp_list) { component.addKeyListener(getShortcutKeyListener()); } } 

方法getAllComponents(frame); Class Common只是一个类,

 public static List getAllComponents(final Container c) { Component[] comps = c.getComponents(); List compList = new ArrayList(); for (Component comp : comps) { compList.add(comp); if (comp instanceof Container) { compList.addAll(getAllComponents((Container) comp)); } } return compList; } 

方法getShortcutKeyListener():

 public static KeyListener getShortcutKeyListener() { KeyListener listener = new KeyListener() { @Override public void keyReleased(KeyEvent evt) { if (evt.getKeyCode() == KeyEvent.VK_F3) { // What you do when F3 key pressed } else if (evt.getKeyCode() == KeyEvent.VK_F2) { // What you do when F2 key pressed } } @Override public void keyTyped(KeyEvent e) { // Do nothing } @Override public void keyPressed(KeyEvent e) { // Do nothing } }; return listener; } 

我认为我们有比这更简单的方法,但这段代码完全符合预期。 关键听众可以在任何forms的工作。

希望这个答案对某人有所帮助。 谢谢。