Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
240 views
in Technique[技术] by (71.8m points)

java - KeyListener won't work?

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) {
}
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...