如何将KeyListener与JFrame一起使用?

时间:2014-02-24 19:29:53

标签: java swing animation jframe

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

绘制了矩形,但每当我点击leftright键时,都没有任何反应。 我有两个类,一个是带有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();
}

}

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

4 个答案:

答案 0 :(得分:7)

由于您未正确使用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();
    }
}

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

答案 1 :(得分:6)

至少有三个问题......

首先...

来自mainFrame的{​​{1}}班extends,但在您的JFrame方法中,您可以通过创建自己的main来创建它的实例并忽略它}。

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

你应该摆脱mainFrame,因为它只会让问题混乱

其次...

extends JFrame只会在注册的组件具有焦点并且具有直接焦点时才会响应关键事件,这会使其不可靠。

相反,您应该将key bindings APIKeyListener面板一起使用,这样可以解决焦点问题。

第三...

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

您应该避免覆盖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;
}

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

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