一旦按下按钮,Java 键事件就不会执行

标签 java swing focus jbutton keyevent

您好,希望有人能告诉我我的关键事件做错了什么。

我正在使用卡片布局来浏览我的两个 JPanels atm。为此,我使用操作事件和关键事件。当按下按钮时, Action 事件将在 JPanel 之间切换,而当按下按键时,按键事件将隐藏按钮。按键事件一切都很好,它做了我想要的事情(在其中一个面板上调用一个方法来设置放置在其中的按钮的边界,例如:button.setBounds(-1, -1, 150, 40);但是当我按下任何按钮,按键事件都不会响应,尽管我按下的按钮上没有任何事件。下面是我的代码,为了简单起见,我删除了面板的不相关部分,就像它们应该做的那样。

预先感谢,如果我需要提供更多线索或更多编辑代码,请告诉我,我会尽力使代码更清晰。

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

最佳答案

这是一个焦点问题。使用按键绑定(bind)而不是 KeyListener,这样您就不必担心这个问题(还有其他好处 - 请查看 Key Bindings tutorial 了解详细信息)。

这是我的 SSCCE这证明了我在说什么。请注意,KeyListener 和键绑定(bind)都会起作用,直到您按下按钮,然后只有绑定(bind)才起作​​用:

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

关于一旦按下按钮,Java 键事件就不会执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9150034/

相关文章:

java - JPanel、BorderLayout 工作错误

java - 在java中删除选定的图像

javascript - 如何使 $(this) 选择器聚焦于当前元素?

Java JFrame 在可见时保持焦点

java - "Cannot refer to a non-final variable buttonflag inside an inner class defined in a different method"

android - Android 中 OCR 的哪个 FOCUS_MODE

java - 如何在 Java 配置类中设置 Spring weaver 选项?

java - 使用 Joda 有效获取时间单位

java - 隐藏 TextView 直到按下 Button

java - 这种添加是否保留了 DFS 的空间和时间复杂度?