KeyListener不起作用?

时间:2014-07-03 23:39:05

标签: java swing jframe keylistener

我正在尝试制作一个名为Duck Simulator的非常简单的2帧程序。 这有一个JFrame和2张图片。如果你想知道它做了什么,它只是一个JFrame,有一个坐在池塘里的鸭子的起始图片。它有一个JLabel说“按D喝水!”当你按D时,它应该将图像设置为鸭子饮用。 它显示了JFrame中坐在池塘中的鸭子的开场图像,但是当我按下D时,它没有做任何事情。

以下是代码:

package net.ducksimulator.classes;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class a implements KeyListener {
static JFrame f;
public static void main (String[] args) {
    f = new JFrame("Duck Simulator ALPHA");
    try {
        f.setContentPane(new JLabel(new ImageIcon(ImageIO.read(new File("images/duck-sitting.png")))));
    } catch (IOException e) {
        System.out.println("Image doesn't exist.");
    }

    f.setResizable(false);
    f.setVisible(true);

    JLabel l = new JLabel("Press D to drink water!");
    l.setBounds(250,20,100,10);
    f.add(l);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.pack();
    f.setLocationRelativeTo(null);
}

public void drink() throws IOException {
    f.setContentPane(new JLabel(new ImageIcon(ImageIO.read(new File("images/duck-drinking.png")))));
}

public void sit() throws IOException {
    f.setContentPane(new JLabel(new ImageIcon(ImageIO.read(new File("images/duck-sitting.png")))));
}

@Override
public void keyPressed(KeyEvent e) {
    int key = e.getKeyCode();
    if (key == KeyEvent.VK_D) {
        try {
            drink();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }
}

@Override
public void keyReleased(KeyEvent e) {
    int key = e.getKeyCode();
    if (key == KeyEvent.VK_D) { 
        try {
            System.out.println("Bagels");
            sit();
        } catch (IOException e1) {

            e1.printStackTrace();
        }
    }
}

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

1 个答案:

答案 0 :(得分:2)

仅仅实施KeyListener还不够,您需要指定要接收关键事件的组件。

这就是问题的起点。 KeyListener只会为具有焦点且可聚焦的组件引发事件。

更好的解决方案是使用key bindings API,它可以让您在触发关键事件之前更好地控制组件所需的焦点水平

至少有两个原因,你应该避免使用setBounds

首先,您添加组件的容器受布局管理器(在此实例中为BorderLayout)的控制,这使setBounds的使用毫无意义,其次,您不会控制在不同平台上呈现时组件可能需要的所需空间量的因素,例如字体度量和渲染管道。让布局经理做好工作