Java Key Event не будет выполняться после нажатия кнопки - PullRequest
2 голосов
/ 05 февраля 2012

Привет, надеюсь, кто-нибудь скажет мне, что я делаю не так с моим ключевым событием.

Я использую макет карты для навигации по двум моим банкоматам JPanels.Для этого я использую Action Events, а также Key Events.События действия будут переключаться между JPanels при нажатии кнопки, в то время как события клавиш будут скрывать кнопки при нажатии кнопки.Все хорошо с ключевыми событиями, он делает то, что я хочу (вызвать метод на одной из панелей, чтобы установить границы кнопок, помещенных в него eq: 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);
    }
}

1 Ответ

5 голосов
/ 05 февраля 2012

Это вопрос фокуса. Используйте привязки клавиш вместо KeyListener, чтобы вам не пришлось беспокоиться об этой проблеме (а также о других преимуществах - см. Учебник Связывания клавиш для получения подробной информации).

Вот мой SSCCE , который демонстрирует, о чем я говорю. Обратите внимание, что KeyListener и привязки клавиш работают до тех пор, пока вы не нажмете кнопку, и тогда будут работать только привязки:

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