Search code examples
javaswingkeyeventbufferstrategy

KeyEvent not getting generated due to BufferStrategy


So I'm making a game, and my main Game application is running fine. The problem is, when I try to launch my game through a menu (using a button ActionEvent, for instance), my game can't seem to detect KeyEvents given to it. So I decided to make a bare-bones version of the code where the problem is:

class Response
{
    static JFrame frame;
    static BufferStrategy strategy;
    public Response()
    {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setUndecorated(true);
        frame.setIgnoreRepaint(true);
        frame.addKeyListener(new KeyAdapter() {
        public void keyTyped(KeyEvent e)
        {
            System.exit(0);
        }
        });
        frame.setVisible(true);
        frame.createBufferStrategy(2);
        strategy = frame.getBufferStrategy();

        frame.requestFocus();
    }
    public static void mainLoop()
    {
        while(true)
        strategy.show();
    }
}

class Button implements ActionListener
{
    JFrame f;
    JButton b;
    public Button()
    {
        f = new JFrame();
        f.setExtendedState(JFrame.MAXIMIZED_BOTH);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        b = new JButton("Click lol");
        b.setFocusable(false);
        b.addActionListener(this);
        f.add(b);
        f.setVisible(true);
        f.setFocusable(false);
    }

    public void actionPerformed(ActionEvent e)
    {
        f.dispose();
        new Response();
        Response.mainLoop();
    }

    public static void main(String args[])
    {
        new Button();
    }
}

After clicking the button here, I get a blank screen, as expected, but it does not detect the KeyTyped event, and upon checking, it appears that Response.frame does not have the focus.

However, if I change the contents of main() to new Response(); Response.mainLoop();, the KeyEvent gets detected.

The setFocusable() methods have been called in the hopes that the components in Button pass on the focus to the Response frame. (After a few hours trying to find the solution, I have concluded that JFrames which use a BufferStrategy cannot be focused on (Although I haven't seen it written anywhere explicitly, so feel free to correct me).

Any idea what's happening?

Thanks in advance.


Solution

  • Generally the focus seems to be a rather slippery thing in java/swing. I have experienced that components do not have the focus even after calling specific methods that should give the focus to those components. After calling setFocusable() and, if present setEnabled() on any swing component, you should be able to set the focus on that component by clicking on it once the application is running and by what I know this is the best one can achieve and that is guaranteed to work. Never, though, rely on components just passing the focus on in the way you would like it. This is not likely to happen.