为什么 JFrame 没有注册“ESC”被按下?

时间:2021-06-21 01:47:32

标签: java swing jframe jpanel keylistener

在我的游戏中,我希望玩家能够按 ESC 并激活菜单。在此菜单中,他们将能够返回主屏幕。我已尝试使用 .addKeyListener(),如下所示。我曾尝试使用 event.getKeyCode() == 27event.getKeyCode() == KeyEvent.VK_ESCAPE,但它似乎没有改变结果(JFrame 未注册“ESC”被按下。

我的代码有问题吗?或者我只是错过了一些明显的东西..

代码(如果你有答案,请参考这个):

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.border.*;
public class Main {
  static JFrame jframe = new JFrame();
  static JLabel startingTitle = new JLabel("Welcome!");
  static JPanel aiPanel = new JPanel();
  static Font buttonFont = new Font("MineCrafter", Font.BOLD, 20);
  static JFrame gameScreen = new JFrame();
  static JFrame onevoneScreen = new JFrame();
  static JFrame escScreen = new JFrame();
  static JPanel onevonePanel = new JPanel();
  static JFrame aiScreen = new JFrame();
  static JPanel title = new JPanel();
  static JButton onevone = new JButton("Multiplayer");
  static JButton aifight = new JButton("Singleplayer");
  static JButton BackToStart = new JButton("Back");
  public Main(){
    Font myFont = new Font("Serif", Font.BOLD, 30);
    startingTitle.setFont(myFont);
    startingTitle.setAlignmentX(Component.CENTER_ALIGNMENT);
    onevone.setAlignmentX(Component.CENTER_ALIGNMENT);
    aifight.setAlignmentX(Component.CENTER_ALIGNMENT);
    title.setLayout(new BoxLayout(title, BoxLayout.Y_AXIS));
    title.add(Box.createRigidArea(new Dimension(0, 50)));
    title.add(startingTitle);
    title.add(Box.createRigidArea(new Dimension(0, 50)));
    title.add(aifight);
    title.add(Box.createRigidArea(new Dimension(0, 25)));
    title.addKeyListener(new MKeyListener());
    title.add(onevone);
    gameScreen.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    gameScreen.setLocationRelativeTo(null);
    gameScreen.setExtendedState(JFrame.MAXIMIZED_BOTH);    
    gameScreen.add(title);
    gameScreen.pack();
  }
  static void setEscScreen(boolean on){
    escScreen.setVisible(on);
  }
  public static void main(String[] argv) throws Exception {       
    SwingUtilities.invokeLater(Main::new);
    BackToStart.setFont(buttonFont);
    BackToStart.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e){
        aiPanel.setVisible(false);
        onevonePanel.setVisible(false);
        title.setVisible(true);
        gameScreen.add(title);
      }
    });
    JButton startGame = new JButton("Launch");
    startGame.setFont(buttonFont);
    startGame.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e){
        System.out.println("Started");
        jframe.setVisible(false);    
        gameScreen.setVisible(true);
        title.setVisible(true);
      }
    });
    // Creates starting screen
    onevone.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e){
        System.out.println("Activate 1v1");
        title.setVisible(false);
        onevonePanel.setVisible(true);
        gameScreen.add(onevonePanel);
      }
    });
    aifight.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e){
        System.out.println("Activate AI");
        title.setVisible(false);
        aiPanel.setVisible(true);
        gameScreen.add(aiPanel);
      }
    });
    // Creates onevoneScreen
    JLabel onevoneTitle = new JLabel("1v1[In Progress]");
    onevonePanel.add(onevoneTitle);
    onevonePanel.addKeyListener(new MKeyListener());
    // Creates aiScreen
    JLabel aiTitle = new JLabel("ai[In Progress]");
    aiPanel.add(aiTitle);
    aiPanel.addKeyListener(new MKeyListener());
    //Creates escScreen
    escScreen.setLayout(new GridBagLayout());
    escScreen.add(BackToStart, new GridBagConstraints());
    escScreen.getContentPane().setBackground(new Color(211, 211, 211));
    escScreen.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    escScreen.setLocationRelativeTo(null);
    escScreen.setExtendedState(JFrame.MAXIMIZED_BOTH);   
    // Creates launch screen
    jframe.setLayout( new GridBagLayout() );
    jframe.add(startGame, new GridBagConstraints());
    jframe.setSize(400, 350);
    jframe.setVisible(true); 
  }
}
class MKeyListener extends KeyAdapter {
  static boolean escapedOn = false;
  public void keyPressed(KeyEvent event) {
    char ch = event.getKeyChar();
    int e = event.getKeyCode();
    if (e == KeyEvent.VK_ESCAPE){
      if (escapedOn == true){
        System.out.println("escaped off");
        Main.setEscScreen(false);
        escapedOn = false;
      } else if (escapedOn == false){
        System.out.println("escaped on");
        Main.setEscScreen(true);
        escapedOn = true;
      }
    }
  }
}

另一个我想回答的问题(但不是必须回答):我可以将菜单 JFrame 设置为稍微透明吗(以便您可以在后台看到游戏)?如果可以,您是否也可以在答案中实现它?

0 个答案:

没有答案
相关问题