0

In my game, I want the player to be able to press ESC and activate a menu. In this menu, they would be able to return to the home screen. I have tried to use .addKeyListener() as you will see below. I have tried using event.getKeyCode() == 27 and event.getKeyCode() == KeyEvent.VK_ESCAPE, but it doesn't seem to change the outcome(JFrame not registering "ESC" being pressed.

Is there a bug in my code? Or am I just missing something blatant..

Code(refer to this if you have an answer):

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;
      }
    }
  }
}

Another question that I would like to be answered(but doesn't have to be answered): Can I make the menu JFrame slightly transparent(so that you can see the game in the background)? If I can, can you implement it in the answer too?

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • 1
    Key listeners must be on the focused component to work, and yours isn't. – Hovercraft Full Of Eels Jun 21 '21 at 01:52
  • In fact, JPanels cannot accept focus unless they are made focusable and then the focus is requested for them. Better to use Key Bindings regardless, since especially in this instance, it is far easier to get around focus issues without using kludges. – Hovercraft Full Of Eels Jun 21 '21 at 01:53
  • Google search for more similar questions on this site: [java keylistener on jpanel not working site:stackoverflow.com](https://www.google.com/search?q=java+keylistener+on+jpanel+not+working+site:stackoverflow.com) – Hovercraft Full Of Eels Jun 21 '21 at 01:54
  • 1
    1) Don't use static variables, this indicates poor class design. 2) Don't use multiple JFrames. An application should only have a single JFrame. If you need child windows then use a `JDialog`. 3) *JFrame slightly transparent(so that you can see the game in the background)? If I can, can you implement it in the answer too?* - one question per posting. Did you search the site using keywords like `JFrame transparent` or maybe `window transparent`? – camickr Jun 21 '21 at 03:09

0 Answers0