问题
I am trying to make a very simple 2-frame program called Duck Simulator. This has a JFrame and 2 pictures. If you want to know what it does, it just is a JFrame with a starting picture of a duck sitting in a pond. It has a JLabel saying "Press D to drink water!" And when you press D, it is supposed to set the image to the duck drinking. It shows the opening image of the duck sitting in the pond in the JFrame, but when I press D, it doesn't do anything.
Here is the code:
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:
Simply implementing KeyListener isn't enough, you need to specify which component you want to receive key events.
This is where the problems start. KeyListener will only raise events for components that have focus AND are focusable.
A better solution would be to use the key bindings API which provides you with better control over the level of focus a component needs before it will trigger key events
You should avoid using setBounds for, at least, two reasons.
Firstly, the container you adding the component to is under the control of a layout manager (BorderLayout in this instance), which makes the use of setBounds pointless and secondly, you don't control the factors which will alter the required amount of space a component might need when presented on different platforms, such as font metrics and rendering pipelines. Let the layout managers do there job
来源:https://stackoverflow.com/questions/24564760/keylistener-wont-work