所以,我试图使用KeyEvent
(KeyListener
)进行矩形移动,每当我尝试按键时,矩形都不会移动。
绘制了矩形,但每当我点击left
和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();
}
}
请告诉我如何移动矩形。 提前谢谢!
答案 0 :(得分:7)
由于您未正确使用JFrame
,因此矩形未移动。您必须将frame
分配给new mainFrame()
,而不是忽略实例化的mainFrame
对象。
@MadProgrammer指出还有其他一些问题。
以下是修复某些问题的代码:
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);
}
});
}
}
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();
}
}
BTW,使用SwingUtilities
来放置gui更新代码,因为swing对象不是线程安全的。
答案 1 :(得分:6)
至少有三个问题......
来自mainFrame
的{{1}}班extends
,但在您的JFrame
方法中,您可以通过创建自己的main
来创建它的实例并忽略它}。
JFrame
已注册到KeyListener
的实例,这意味着它已被忽略。
你应该摆脱mainFrame
,因为它只会让问题混乱
extends JFrame
只会在注册的组件具有焦点并且具有直接焦点时才会响应关键事件,这会使其不可靠。
相反,您应该将key bindings API与KeyListener
面板一起使用,这样可以解决焦点问题。
你已经破坏了油漆链,这意味着当矩形移动时,之前绘制的内容仍将保留。
您应该避免覆盖Draw
,而是使用paint
。这有很多原因,但一般来说,它在后台绘制,称为子组件的更新。
最后,确保在执行任何其他操作之前调用paintComponent
,以确保为绘制准备super.paintComponent
上下文
请查看Performing Custom Painting了解详情
答案 2 :(得分:-1)
你应该在mainDraw类中添加你的监听器,而不是你的mainFrame。
最好不要在Frames和Windows中处理键和鼠标事件。
O /
答案 3 :(得分:-1)
我试图将整个框架的快捷方式监听器实现并没有成功,最后找到了一种方法。如果要在将焦点设置到另一个组件时设置侦听器,则必须将侦听器添加到所有组件。
这是我的代码,
在构造函数中调用它:
setShortcutListener(this); // this = JFrame when you call in in constructor
方法setShortcutListener(JFrame frame):
private void setShortcutListener(JFrame frame) {
List<Component> comp_list = Common.getAllComponents(frame);
for (Component component : comp_list) {
component.addKeyListener(getShortcutKeyListener());
}
}
方法getAllComponents(frame); Class Common只是一个类,
public static List<Component> getAllComponents(final Container c) {
Component[] comps = c.getComponents();
List<Component> compList = new ArrayList<Component>();
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;
}
我认为我们有比这更简单的方法,但是这段代码完全符合预期。关键听众可以在任何形式上工作。
希望这个答案对某人有所帮助。感谢。