I'm making a simple Java applet that displays a traffic light. If there are no keys being pressed the background is white. If you hit the "1", "2", or "3" keys on the numpad then the traffic light should change colors to respectfully: red, green, and yellow. It is not working because when I press any keys, nothing happens. all isX booleans are initialized to false except for isReleased.

@Override
public void keyPressed(KeyEvent e) {
isReleased = false;
switch(e.getKeyCode()){
    case KeyEvent.VK_NUMPAD1:
        isRed=true;
        break;
    case KeyEvent.VK_NUMPAD2:
        isGreen=true;
        break;
    }

}

@Override
public void keyReleased(KeyEvent e) {
isReleased = true;
}

@Override
public void keyTyped(KeyEvent e) {
}

 @Override
 public void paint(Graphics g) {
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, getWidth(), getHeight());
    g.drawImage(trafficLight, 0, 0, null);

    if(isReleased==true){
        g.drawImage(blank, 0, 0, this);
    }else{
        if(isRed==true){
        g.drawImage(red, 0, 0, this);
    }
    if(isGreen==true){
        g.drawImage(green, 0, 0, this);
        }
    }
}

NOTE
(updated) My full code can be seen here: http://pastebin.com/8ZNQUWJy

有帮助吗?

解决方案

Let's ignore that fact that you code is incomplete, so it's impossible to know what you are extending from or if you've actually added a KeyListener.

KeyListener is notorious for being fickle about it's focus state. Basically, this means, KeyListener will only respond to keystrokes if the component it is registered to is focusable AND has keyboard focus...

A better solution would be to use the Key Bindings API, which provides better control over the focus level that will trigger key events.

You are also breaking the paint chain. Painting is a complex series of method calls, chaining together to produce the final result. By failing to call super.paint, you've broken this chain, introducing the possibility of paint artifacts.

You should also avoid overriding paint generally, but especially of top level containers, like windows, as they are not double buffered. It is recommended that instead, you extend from something JPanel or JComponent and override it's paintComponent method instead.

Take a look at Performing Custom Painting for more details.

Updated based on seeing full source

  • Avoid AWT based components (like Applet) the API is out of date and not many people use it any more, instead you should consider using a JApplet instead. But personally, I would avoid applets until you have a better understanding of the overall API.
  • Don't call setSize within an applet, the size is determined by the html tag which describes the applet to the browser
  • Your run method is pointless as it doesn't actually do anything useful and may actually be causing your application to "hang"
  • Your update method is only painting the trafficLight BufferedImage, but because you fail to call super.update, nothing else is painted. It would be better to grid rid of it and do your painting in the paint method, but make sure you are calling super.paint. But as I already said, you'd be better of using something like JPanel and overriding it's paintComponent method.

Take a look at Creating a GUI with Swing for more details

You may also find Why CS teachers should stop teaching Java applets of some worth...

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top