سؤال

I honestly have no idea what I'm doing wrong.

Sometimes, the key events register and sometimes they don't.
And by that I mean sometimes when I run Frogger2 I get registering events, and sometimes nothing.

It seems completely random, when the key events register or not. Usually if I don't test anything for a while and run Frogger2 the events register and the moment I close it and rerun the exact same program, I get no events.

Please help.

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class Frogger2 extends JPanel {

public static JFrame frame;
public static Frogger2 F;

public Frogger2() {}

public Dimension getPreferredSize() { return new Dimension(500,500); }
public void paintComponent(Graphics g) { super.paintComponent(g); }


private int fdir;

public void moveLeft() {
    travel(2);
}
public void moveRight() {
    travel(0);
}
public void moveUp() {
    travel(3);
}
public void moveDown() {
    travel(1);
}
private void travel(int ddd) {
    System.out.println(ddd);
}


private boolean step() {
    System.out.println("FDIR: "+fdir);
    return true;
}

public void start() {
    fdir = 2;
    while(true) {
        boolean a = step();
        if (!a) break;
        try {
            Thread.sleep(25);
        } catch(Exception e) {}
    }
}

public static void main(String[] args) {
    frame = new JFrame("Frogger");

    F = new Frogger2();
    F.setDoubleBuffered(true);
    frame.add(F);
    frame.pack();
    frame.setVisible(true);
    frame.setResizable(false);
    JPanel abc = (JPanel)frame.getContentPane();
    abc.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left");
    abc.getActionMap().put("left", new AbstractAction() {
        public void actionPerformed(ActionEvent e) {F.moveLeft();}
    });
    abc.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "right");
    abc.getActionMap().put("right", new AbstractAction() {
        public void actionPerformed(ActionEvent e) {F.moveRight();}
    });
    abc.getInputMap().put(KeyStroke.getKeyStroke("UP"), "up");
    abc.getActionMap().put("up", new AbstractAction() {
        public void actionPerformed(ActionEvent e) {F.moveUp();}
    });
    abc.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "down");
    abc.getActionMap().put("down", new AbstractAction() {
        public void actionPerformed(ActionEvent e) {F.moveDown();}
    });

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    F.start();

}

}
هل كانت مفيدة؟

المحلول

This problem usually occurs with focus on the panel, every time you are pressing any key you have to make sure the panel is in focus.
You'll want to look at the Java Tutorial for a good overview of Key Bindings as @camickr mentioned it in the comment.
Also look at question answered by @mKorbel (very interested answer).

The interested thing in Key Bindings is: say when you press on Ctrl+Shift+Space the program do some operation, it's very interesting and highly recommended to use Key Bindings, also see my first question on stack was about this subject.

This your code I'v made some changes :

  • KeyListener every time presses a key the focus will be on the panel.
  • MouseListener When mouse enters on the panel or when a mouse clicks on the panel, again the focus will be on the panel.
  • FocusListener: to know either the panel is focusable or not.

Here is the code :

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
public class MovingJPanel {

    public static void main(String[] args) {
    JFrame frame = new JFrame("Frogger");

    frame.pack();
    frame.setVisible(true);
    frame.setResizable(true);
    frame.setLocationRelativeTo(null);
    frame.setSize(400,400);
    JPanel abc = new JPanel();
    abc.setBackground(Color.CYAN);
    abc.getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left");
    abc.getActionMap().put("left", new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
            System.out.println("LEFT");}
    });
    abc.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "right");
    abc.getActionMap().put("right", new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
            System.out.println("ROIGHT");}
    });
    abc.getInputMap().put(KeyStroke.getKeyStroke("UP"), "up");
    abc.getActionMap().put("up", new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
            System.out.println("UP");}
    });
    abc.getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "down");
    abc.getActionMap().put("down", new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
            System.out.println("DOWN");}
    });

    abc.addFocusListener(new FocusAdapter() {
        @Override
        public void focusGained(FocusEvent e) {
            System.out.println("Focus Gained");
        }
        @Override
        public void focusLost(FocusEvent e) {
            System.out.println("Focus Lost");
        }  
});
    abc.addKeyListener(new KeyAdapter() {
        @Override
        public void keyTyped(KeyEvent e) {
            JPanel p = (JPanel)e.getSource();
            p.requestFocus();
        } 
});

    abc.addMouseListener(new MouseAdapter() {

        @Override
        public void mouseEntered(MouseEvent e) {
           JPanel p = (JPanel)e.getSource();
            p.requestFocus();
        }

});
    frame.getContentPane().add(abc,"Center");
    frame.getContentPane().add(new JButton("Click Me"),"North");
    abc.requestFocusInWindow();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top