Java Key Event won't execute once I press a button

↘锁芯ラ 提交于 2019-12-24 02:03:43

问题


Hi hope someone can tell me what I am doing wrong with my Key Event.

I am using a Card Layout to navigate through two of my JPanels atm. To do so I use Action Events as well as Key Events. The action events will toggle between JPanels when a button is pressed while the key events will hide away the buttons when a key is pressed. All good with the key events, it does what I want (call a method on one of the panels to set the bounds of the buttons placed inside it eq: button.setBounds(-1, -1, 150, 40); but when I press any of the buttons the key event wont respond despite not having any event on the buttons that I press. Below is my code, for simplicity I removed the non relevant parts of the panels like what they are meant to do.

Thanks in advance and please let me know if I need to provide more clues or to edit the code more, I will try my best to make the code clearer.

public class PanelContainer extends JPanel implements ActionListener, KeyListener{
    GamePanel game = new GamePanel();
    MainMenuPanel mainMenu = new MainMenuPanel();
    CardLayout cards = new CardLayout();
    public PanelContainer(){
        setLayout(cards);
        this.setFocusable(true);
        this.addKeyListener(this);
        mainMenu.newGameButton.addActionListener(this);
        add(mainMenu, "Card1");
        add(game, "Card2");
    }
    @Override
    public void actionPerformed(ActionEvent aevt){
        cards.show(this, "Card2");
        game.action();
    }
    @Override
    public void keyTyped(KeyEvent kevt){

    }
    @Override
    public void keyPressed(KeyEvent kevt){

    }
    @Override
    public void keyReleased(KeyEvent kevt){
        if(kevt.getKeyCode() == KeyEvent.VK_ESCAPE || kevt.getKeyChar() == 'O' ||    kevt.getKeyChar() == 'o'){
            game.shw(); //shw() is a method inside GamePanel that sets the bounds of the buttons
        }
        else if (kevt.getKeyChar() == 'h' || kevt.getKeyChar() == 'H'){game.hid();}
    }
}





public class MainMenuPanel extends JPanel
{
    private URL workingDir = this.getClass().getResource("imgresources/brick_wall.png") ;
    private ImageIcon icon = new ImageIcon(workingDir) ;
    private Image img = icon.getImage();
    //create and initiate buttons;
    JButton newGameButton = new JButton("New Game"); 
    JButton highScoreButton = new JButton("High Scores");
    JButton controlsButton = new JButton("Controls");
    Point[] points = new Point[1000];

    public MainMenuPanel(){
        add(newGameButton);
        add(highScoreButton);
        add(controlsButton);
        setPoints();
    }

    public void setButtonsBounds(){
        newGameButton.setBounds(450, 200, 200, 40);
        highScoreButton.setBounds(450, 250, 200, 40);
        controlsButton.setBounds(450, 300, 200, 40);
    }

    @Override
    public void paintComponent(Graphics g){
        try{
            super.paintComponent(g);
            Graphics2D d2 = (Graphics2D) g;
            d2.setColor(new Color(0, 0, 0));
            d2.fillRect(0, 0, this.getWidth(), this.getHeight());

            setButtonsBounds();
            for(int i=0; i<275; i++){
                d2.drawImage(img, points[i].x +200, points[i].y, this);
            }
        }catch(Exception e){}
    }
}





public class GamePanel extends JPanel implements Runnable{
    JButton button = new JButton("Main Menu");
    JButton button2 = new JButton("Exit Game");
    void shw(){
       add(button);
       add(button2);
       button.setBounds(400, 200, 150, 20);
       button2.setBounds(400, 240, 150, 20);

    }
    void hid(){
       button.setBounds(1, 1, 150, 20);
       button2.setBounds(1, 40, 150, 20);
    }
}

回答1:


It's a focus issue. Use Key Bindings instead of a KeyListener so you don't have to worry about this issue (and for other benefits as well -- check the Key Bindings tutorial for details).

Here's my SSCCE that demonstrates what I'm talking about. Note that both KeyListener and key bindings work until you press a button, and then only bindings work:

import java.awt.event.*;
import javax.swing.*;

public class KeyBindingsEg {
   private static void createAndShowGui() {
      PanelContainer mainPanel = new PanelContainer();

      JFrame frame = new JFrame("KeyBindingsEg");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

@SuppressWarnings("serial")
class PanelContainer extends JPanel {

   public PanelContainer() {
      this.setFocusable(true);
      this.addKeyListener(new MyKeyListener());
      JButton newGameButton = new JButton("New Game");
      newGameButton.addActionListener(new MyActionListener());
      add(newGameButton);
      setKeyBindings();
   }

   private void setKeyBindings() {
      Action hideAction = new BindingAction(BindingAction.HIDE);
      Action showAction = new BindingAction(BindingAction.SHOW);
      int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
      InputMap inputMap = getInputMap(condition);
      ActionMap actionMap = getActionMap();

      actionMap.put(BindingAction.HIDE, hideAction);
      inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_H, 0), BindingAction.HIDE);
      inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_H, KeyEvent.SHIFT_DOWN_MASK),
            BindingAction.HIDE);

      int[] showKeys = { KeyEvent.VK_O, KeyEvent.VK_ESCAPE };
      actionMap.put(BindingAction.SHOW, showAction);
      for (int key : showKeys) {
         inputMap.put(KeyStroke.getKeyStroke(key, 0), BindingAction.SHOW);
         inputMap.put(KeyStroke.getKeyStroke(key, KeyEvent.SHIFT_DOWN_MASK),
               BindingAction.SHOW);
      }

   }

   private class MyActionListener implements ActionListener {
      @Override
      public void actionPerformed(ActionEvent aevt) {
         System.out.println("button pressed");
      }
   }

   private class MyKeyListener extends KeyAdapter {
      public void keyReleased(KeyEvent kevt) {
         if (kevt.getKeyCode() == KeyEvent.VK_ESCAPE
               || kevt.getKeyChar() == 'O' || kevt.getKeyChar() == 'o') {
            System.out.println("KeyListener: show");
         } else if (kevt.getKeyChar() == 'h' || kevt.getKeyChar() == 'H') {
            System.out.println("KeyListener: hide");
         }
      }
   }

   private class BindingAction extends AbstractAction {
      public static final String HIDE = "Hide";
      public static final String SHOW = "Show";

      public BindingAction(String text) {
         super(text);
         putValue(ACTION_COMMAND_KEY, text);
      }

      @Override
      public void actionPerformed(ActionEvent evt) {
         String actionCommand = evt.getActionCommand();
         if (actionCommand.equals(HIDE)) {
            System.out.println("key bindings: hide");
         } else if (actionCommand.equals(SHOW)) {
            System.out.println("key bindings: show");
         }
      }
   }
}


来源:https://stackoverflow.com/questions/9150034/java-key-event-wont-execute-once-i-press-a-button

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!