My JFrame is not changing when key pressed

2019-08-30 01:36发布

问题:

I have a Jframe set on a timer and im trying to change one of the pictures by pressing the down key (special code 40), yet nothing is happening.

import javax.swing.JFrame;
import javax.swing.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.*;
import java.awt.image.BufferedImage;

public class MenuScreen extends JFrame {
private static JFrame frame;
GameKeyboard GK;

boolean gamePlay = false;
boolean gameQuit = false;
boolean gameTwoPlayer = false;
String option;

//set dimension of window and buttons
public final int screenWidth = 800; // Width of window
public final int screenHeight = screenWidth / 12 * 9; // Height of window

private static Graphics gr;

//store images
private static Image background;
private static Image play;
private static Image twoPlayer;
private static Image quit;
private static Image playSelected;
private static Image twoPlayerSelected;
private static Image quitSelected;

public MenuScreen() {
    frame = new JFrame();
    setSize(screenWidth, screenHeight);

    //         frame.pack();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    frame.setTitle("Space Wars Menu");
    frame.setLocation(0, 0);


    BufferedImage canvas=new BufferedImage(920,720,BufferedImage.TYPE_INT_ARGB);

    gr=canvas.getGraphics();

    JLabel label=new JLabel(new ImageIcon(canvas));
    frame.add(label);

    MenuKeyboard.initialise();

    //load images
    background = GameImage.loadImage("Images//background.jpg");
    play = GameImage.loadImage("Images//play.png");
    playSelected = GameImage.loadImage("Images//playSelected.png");
    twoPlayer = GameImage.loadImage("Images//twoPlayer.png");
    twoPlayerSelected = GameImage.loadImage("Images//twoPlayerSelected.png");
    quit = GameImage.loadImage("Images//quit.png");
    quitSelected = GameImage.loadImage("Images//quit.png");

    //draw images
    gr.drawImage(background, 0, 0, null);
    gr.drawImage(playSelected, 180, -50, null);
    gr.drawImage(twoPlayer, 180, 50, null);
    gr.drawImage(quit, 180, 150, null);

    ActionListener taskPerformer = new ActionListener()      
        {
            public void actionPerformed(ActionEvent evt)
            {
                doTimerAction();
            }
        };
    Timer t = new Timer(25, taskPerformer);
    t.start();
}

private static void doTimerAction() {

    int specialKey = MenuKeyboard.getSpecialKey();

    if (specialKey == 40) //if down pressed
    {
        gr.drawImage(twoPlayerSelected, 160, 150, null);
        gr.drawImage(play, 160, -50, null);

    }

  }

}

HOWEVER, when I add extra code like:

 if (specialKey == 40) //if down pressed
    {

        gr.drawImage(twoPlayerSelected, 160, 150, null);
        gr.drawImage(play, 160, -50, null);

        Game game = new Game();
        game.start();

    }

and then press down when running it it then works and send me onto my game class!

Any one got any suggestions?

回答1:

Read the Key Bindings link that I provided to you in your previous question (and provided again here), as use of this would work best in this situation. A Timer is for repeated actions, which is not what you're trying to do. You need to respond to an event, and the Key Bindings will help you do that.

For example:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class MenuScreen2 extends JPanel {
   private static final int PREF_W = 800;
   private static final int PREF_H = (9 * PREF_W) / 12;
   private JLabel label = new JLabel("", SwingConstants.CENTER);

   public MenuScreen2() {
      setLayout(new GridBagLayout());
      add(label);
      label.setFont(label.getFont().deriveFont(Font.BOLD, 50));
      setBackground(Color.cyan);

      // Key Bindings is done in the code below
      // the down String will be used to tie the down keystroke put into the InputMap
      // with the DownAction put into the ActionMap
      String down = "down";
      getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), down);
      getActionMap().put(down, new DownAction());
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   // This is the Action used in our Key Bindings
   private class DownAction extends AbstractAction {
      @Override
      public void actionPerformed(ActionEvent arg0) {
         label.setText("Time To Start The Game!");
      }
   }

   public static void main(String[] args) {
      // run our Swing application in a thread-safe way
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            MenuScreen2 mainPanel = new MenuScreen2();

            JFrame frame = new JFrame("Menu Screen");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(mainPanel);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
         }
      });
   }
}