I am trying to create Menu to may 2D game in Java. But the game is not responding to pressed keyes. Menu is working, but when I choose new game in menu, game starts but it does not react to pressed keyes. But, when I remove menu, game is responding to pressed keys ... but when there is also menu, it is not responding. How to solve this problem ?

Here is Sokoban class:

package sokoban;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;


import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;


public final class Sokoban extends JFrame  {


    private Menu menu;
    private Board board;
    private static JFrame myFrame;


    public Sokoban() {
        InitUI();
    }

    public void InitUI() {

        myFrame = new JFrame();

        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myFrame.setSize(800,600);
        myFrame.setLocationRelativeTo(null);
        myFrame.setTitle("Labyrint");
        myFrame.setResizable(false);

        board = new Board();
        menu = new Menu(); 

        myFrame.add(menu);

//-----------

        JMenu file = new JMenu("File");
        file.setMnemonic('F');
        JMenuItem newItem = new JMenuItem("New");
        newItem.setMnemonic('N');
        file.add(newItem);
        JMenuItem openItem = new JMenuItem("Open");
        openItem.setMnemonic('O');
        file.add(openItem); 
        JMenuItem exitItem = new JMenuItem("Exit");
        exitItem.setMnemonic('x');
        file.add(exitItem);

        //adding action listener to menu items
        newItem.addActionListener(
            new ActionListener(){
                public void actionPerformed(ActionEvent e)
                {
                    menu.setVisible(false);

                    menu = null;
                    myFrame.add(board);
                }
            }
        );
        openItem.addActionListener(
            new ActionListener(){
                public void actionPerformed(ActionEvent e)
                {
                    System.out.println("Open is pressed");
                }
            }
        );
        exitItem.addActionListener(
            new ActionListener(){
                public void actionPerformed(ActionEvent e)
                {
                    System.out.println("Exit is pressed");
                }
            }
        );                      
        JMenuBar bar = new JMenuBar();
        myFrame.setJMenuBar(bar);
        bar.add(file);

        myFrame.getContentPane();

        myFrame.setVisible(true);
        ///------------------------------------

    }


    public static void main(String[] args) {


        Sokoban sokoban = new Sokoban();


    }



}

And this is game, part of Board.class (not responding to pressed keyes when Menu is working):

public class Board extends JPanel implements KeyListener { 
public Board() {

        addKeyListener(this);
        setFocusable(true);

        initWorld();

    }

    /* not importnant code for this problem here*/

    @Override
    public void keyPressed(KeyEvent e) {

        int key = e.getKeyCode();


        if (key == KeyEvent.VK_LEFT) {
            if ((checkWallCollision(soko,LEFT_COLLISION)) == true) {

                return;

            }

            if (checkBagCollision(LEFT_COLLISION)) {
                return;
            }

            soko.move(-SPACE, 0);
            score++;
            celkove_score++;

        } else if (key == KeyEvent.VK_RIGHT) {
        etc.
        .
        .
        .
}

Have you looked at using key binding instead of key listener?

In my code ... I need InputMap and Actionmap for menu and board in class Sokoban?

Have you tried writing a small program to work out how to use key bindings?
When you understand how it works, you will be able to use the technique in the Sokoban program.

so, I put this into Sokoban.class:

private static Action enterAction;

into method InitUI in Sokoban.class:

    enterAction = new EnterAction();
    menu.getInputMap().put( KeyStroke.getKeyStroke( "ENTER" ), "doEnterAction" );
    menu.getActionMap().put( "doEnterAction", enterAction );

    static class EnterAction extends AbstractAction
{
    public void actionPerformed( ActionEvent tf )
    {

        System.out.println( "The Enter key has been pressed." );
        menu.setVisible(false);

        menu = null;
        myFrame.add(board);

    } // end method actionPerformed()

} // end class EnterAction

This works. When I press Enter key on keyboard, the game appears, It is OK.

So I put similar code into Board.class:

private static Action rightAction;

and into constructor of Board:

rightAction = new RightAction();




    this.getInputMap().put( KeyStroke.getKeyStroke( "RIGHT" ), "doRightAction" );
    this.getActionMap().put( "doRightAction", rightAction );

    initWorld();

    static class RightAction extends AbstractAction
{
    public void actionPerformed( ActionEvent tf )
    {

        System.out.println( "The Right key has been pressed." );



    } // end method actionPerformed()

} // end class EnterAction

But nothing happens in game, when I press RIGHT key on keyboard. What is wrong ?

actually, it is the same as before ... when there is not menu, it is responding to keys in game .. but when there is also a menu, only menu in responding to pressed keys .. game is not responding.

Can you make a small program that compile, executes and shows the problem?

here is small program, made in Eclipse:
https://dl.dropbox.com/u/55962224/my_program.rar

If you run it, menu appears (white rectangle) and when you press enter key, game appears (blue rectangle) .. and when you press Right key nothing happens in game (it should write into output console: The Right key has been pressed.)

Please post the code here vs a link.

Ok, code is here:
my_program.class

import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JFrame;
import javax.swing.KeyStroke;


public final class my_program extends JFrame  {

    private static Menu menu;
    private static Game game;
    private static JFrame myFrame;
    private static Action enterAction;



    public my_program() {

        myFrame = new JFrame();

        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myFrame.setSize(300,300);
        myFrame.setLocationRelativeTo(null);
        myFrame.setTitle("Title");
        myFrame.setResizable(false);

        game = new Game();
        menu = new Menu(); 


        myFrame.add(menu); //if you replace this with: myFrame.add(game); only game appears, without menu and right key is responding


        enterAction = new EnterAction();

        menu.getInputMap().put( KeyStroke.getKeyStroke( "ENTER" ), "doEnterAction" );
        menu.getActionMap().put( "doEnterAction", enterAction );

        myFrame.setVisible(true);

    }



    static class EnterAction extends AbstractAction
    {
        public void actionPerformed( ActionEvent tf )
        {

            System.out.println( "The Enter key has been pressed." );
            menu.setVisible(false);
            myFrame.add(game);

        } 

    } 



    public static void main(String[] args) {

        my_program program = new my_program();

    }

}

Menu.class

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;

public class Menu extends JPanel {

    public Menu() {

    }

    public void paint(Graphics g) {

        super.paint(g);

        g.setColor(Color.white);
        g.fillRect(10, 10, 120, 30);

    }


}

Game.class

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JPanel;
import javax.swing.KeyStroke;



public class Game extends JPanel { 

    private static Action rightAction;


    public Game() {

        rightAction = new RightAction();

        getInputMap().put( KeyStroke.getKeyStroke( "RIGHT" ), "doRightAction" );
        getActionMap().put( "doRightAction", rightAction );

    }

    static class RightAction extends AbstractAction
    {
        public void actionPerformed( ActionEvent tf )
        {

            System.out.println( "The Right key has been pressed." );


        } 

    } 



    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;

        g.setColor(Color.blue);
        g.drawRect(20, 20, 120, 30);

    }


}

ok, I renamed it. But it did not solve my problem ... can you help me please ?

We cross posted. See my last post.

Thanks! It is responding now ... everything is OK now.

I have one more question. How can I put in code this (using that key bindings):

if(ENTER IS PRESSED) { 
System.out.println("text");
}

I mean, what to put instead of (ENTER IS PRESSED) ... I want to do some action only when enter is pressed .. when it is not pressed at that specific moment, do something else. Hope you understand what I mean.

do some action only when enter is pressed

Put the code in the listener that is called when Enter is pressed.

but I need something different .. I need this:

//some code
.
.
.
//end of some code
if(enter is pressed) {
    //continue doing something
} else { 
   //waiting for pressed enter, continue only when enter is pressed
   }

Events like key presses don't work that way. You need to use a listener that is called when the event happens. The code should show a window with a button and then exit to the jvm to await the user pressing the button. When the button is pressed, the event listener is called.

If you want to pause the execution of a method, you might be able to use something like the wait() notify() methods. Call wait() in at the place you want to pause execution and call notify() for that wait() in the listener method.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.