-2

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) {
}
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 2
    Did you even read any of the other questions in the forum on this topic? See the posting on the right side of the page under the "Releated" heading for postings that will help. – camickr Jul 04 '14 at 00:39
  • By the time of deployment, those image based resources will likely become an [tag:embedded-resource]. That being the case, the resource must be accessed by `URL` instead of `File`. See the [info page](http://stackoverflow.com/tags/embedded-resource/info) for the tag, for a way to form an `URL`. – Andrew Thompson Jul 04 '14 at 01:06
  • possible duplicate of [KeyListener isn't working?](http://stackoverflow.com/questions/11211472/keylistener-isnt-working) – Andrew Thompson Jul 04 '14 at 01:07

1 Answers1

2

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

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • You have to love blind down voting. This doesn't provide people the means to learn or the opportunity to improve on their answers – MadProgrammer Jul 04 '14 at 20:39