We're a community of 1.1M IT Pros here for help, advice, solutions, professional growth and fun. Join us!
1,080,623 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Start New Discussion Reply to this Discussion

Keylistener - not responding (creating menu)

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.
        .
        .
        .
}
2
Contributors
19
Replies
2 Days
Discussion Span
7 Months Ago
Last Updated
20
Views
marek2121
Newbie Poster
14 posts since Nov 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

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

NormR1
Posting Sage
Team Colleague
7,742 posts since Jun 2010
Reputation Points: 1,158
Solved Threads: 793
Skill Endorsements: 16

I found this: http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html

but I do not understand how to use it in my case :/

can you please edit my code for using binding ... so I will see how it works ? ty

marek2121
Newbie Poster
14 posts since Nov 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

Copy one of the examples from the tutorial and experiment with it so you see how they work.
Here's a sample from the forum:
http://www.daniweb.com/software-development/java/threads/430890/actionlistener-causing-keybindings-to-fail#post1846783

If you have problems with it, post the code and ask your questions about the problems.

Can you explain what problems you see using bindings vs listeners?

NormR1
Posting Sage
Team Colleague
7,742 posts since Jun 2010
Reputation Points: 1,158
Solved Threads: 793
Skill Endorsements: 16

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

marek2121
Newbie Poster
14 posts since Nov 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

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.

NormR1
Posting Sage
Team Colleague
7,742 posts since Jun 2010
Reputation Points: 1,158
Solved Threads: 793
Skill Endorsements: 16

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 ?

marek2121
Newbie Poster
14 posts since Nov 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

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.

marek2121
Newbie Poster
14 posts since Nov 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

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

NormR1
Posting Sage
Team Colleague
7,742 posts since Jun 2010
Reputation Points: 1,158
Solved Threads: 793
Skill Endorsements: 16

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.)

marek2121
Newbie Poster
14 posts since Nov 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

Please post the code here vs a link.

NormR1
Posting Sage
Team Colleague
7,742 posts since Jun 2010
Reputation Points: 1,158
Solved Threads: 793
Skill Endorsements: 16

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

    }


}
marek2121
Newbie Poster
14 posts since Nov 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

BTW Menu is the name of a class in the Java SE java.awt package. It's confusing to use that name for your class

Did you read this:
http://www.daniweb.com/software-development/java/threads/430890/actionlistener-causing-keybindings-to-fail#post1846783

Try this:
getInputMap(WHEN_IN_FOCUSED_WINDOW).put( KeyStroke.getKeyStroke( "RIGHT" ), "doRightAction" );

NormR1
Posting Sage
Team Colleague
7,742 posts since Jun 2010
Reputation Points: 1,158
Solved Threads: 793
Skill Endorsements: 16

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

marek2121
Newbie Poster
14 posts since Nov 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

We cross posted. See my last post.

NormR1
Posting Sage
Team Colleague
7,742 posts since Jun 2010
Reputation Points: 1,158
Solved Threads: 793
Skill Endorsements: 16

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

marek2121
Newbie Poster
14 posts since Nov 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

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.

marek2121
Newbie Poster
14 posts since Nov 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

do some action only when enter is pressed

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

NormR1
Posting Sage
Team Colleague
7,742 posts since Jun 2010
Reputation Points: 1,158
Solved Threads: 793
Skill Endorsements: 16

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
   }
marek2121
Newbie Poster
14 posts since Nov 2012
Reputation Points: 0
Solved Threads: 0
Skill Endorsements: 0

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.

NormR1
Posting Sage
Team Colleague
7,742 posts since Jun 2010
Reputation Points: 1,158
Solved Threads: 793
Skill Endorsements: 16

This article has been dead for over three months: Start a new discussion instead

Post: Markdown Syntax: Formatting Help
 
You
 
© 2013 DaniWeb® LLC
Page generated in 0.1231 seconds using 2.81MB