【问题标题】:How do you make key bindings for a java.awt.Frame?如何为 java.awt.Frame 进行键绑定?
【发布时间】:2012-09-08 05:19:42
【问题描述】:

背景

我的窗口是 java.awt.Frame,Frame 内部是两个 Panels (java.awt.Panel)。我正在尝试让窗口处理我按下的按钮。

尝试 1 号

我尝试使用 KeyListener,使 Frame 实现 KeyListener。我将 KeyListener 添加到 Frame 中,但是当我按下键时 KeyListener 函数没有做任何事情。 (我尝试使用 System.out.println() 进行打印。)

尝试 2 号

我尝试按照本教程进行操作:http://tips4java.wordpress.com/2008/10/10/key-bindings/。这是我尝试处理按空格键的操作:

public void registerActions(){                                  //01
  Action myAction = new AbstractAction(){                       //02
    @Override                                                   //03
    public void actionPerformed(ActionEvent e) {                //04
      System.out.println("GREAT SUCCESS!");                     //05
    }                                                           //06
  };                                                            //07
  KeyStroke key = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0); //08
  component.getInputMap().put(key, "myAction");                 //09
  component.getActionMap().put("myAction", myAction);           //10
}                                                               //11

主要问题是我不知道第 09 行和第 10 行中的“组件”应该是什么,因为我的应用程序没有任何 JComponents。

我的问题

有没有办法在不使用摆动组件的情况下做到这一点?还是有其他处理按键的方法?

【问题讨论】:

  • 我很好奇你为什么不使用 Swing。它是旧版应用吗?
  • 我最终要让我的程序成为多线程的,而且我听说 Swing 不是线程安全的。
  • 线程安全与GUI更新有关,并不是说不能使用线程。网络上有很多资源可供您阅读,以了解如何在使用 Swing 时处理线程。
  • 尝试使用根窗格或内容窗格。请记住,子组件可能会在到达您之前消耗按键
  • @nobrainer 我会改用 JPanel。直接应用 KeyBindings 并使用它的 paintCompont 方法来绘制图形。您需要确保将面板设置为可聚焦

标签: java swing jframe key-bindings keylistener


【解决方案1】:

我发现我可以使用 AWTEventListener 来做到这一点。

public class MyFrame extends Frame implements AWTEventListener {

  ...

  public MyFrame(String title){
    super(title);
    ...
    this.getToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
  }

  @Override
  public void eventDispatched(AWTEvent event) {
    if(event instanceof KeyEvent){
      KeyEvent key = (KeyEvent)event;
      if(key.getID()==KeyEvent.KEY_PRESSED){ //Handle key presses
        System.out.println(key.getKeyChar());
        //TODO: do something with the key press
        key.consume();
      }
    }
  }
}

【讨论】:

    【解决方案2】:

    好的,这是一个使用 JPanel 的示例。

    我创建了一个Frame,将其布局设置为BorderLayout 添加到KeyPane,然后瞧...

    public class KeyPane extends JPanel {
    
        private Timer paintTimer;
        private MouseFocusHandler mouseFocusHandler;
    
        private boolean spaceOn = false;
        private int yPos = 0;
        private int direction = 2;
    
        private Rectangle blob = new Rectangle(0, 0, 10, 10);
    
        public KeyPane() {
    
            setFocusable(true);
    
            InputMap im = getInputMap(WHEN_FOCUSED);
            ActionMap am = getActionMap();
    
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "Space");
            am.put("Space", new SpaceAction());
    
            setPreferredSize(new Dimension(100, 100));
    
            getPaintTimer().setCoalesce(false);
            getPaintTimer().start();
    
        }
    
        @Override
        public void addNotify() {
            super.addNotify();
            requestFocusInWindow();
            addMouseListener(getMouseFocusHandler());
            getPaintTimer().start();
        }
    
        @Override
        public void removeNotify() {
            removeMouseListener(getMouseFocusHandler());
            getPaintTimer().stop();
            super.removeNotify();
        }
    
        protected Timer getPaintTimer() {
            if (paintTimer == null) {
                paintTimer = new Timer(40, new RepaintAction());
                paintTimer.setRepeats(true);
                paintTimer.setCoalesce(true);
            }
            return paintTimer;
        }
    
        protected MouseFocusHandler getMouseFocusHandler() {
            if (mouseFocusHandler == null) {
                mouseFocusHandler = new MouseFocusHandler();
            }
            return mouseFocusHandler;
        }
    
        @Override
        protected void paintComponent(Graphics g) {
    
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
    
            int width = getWidth() - 1;
            int height = getHeight() - 1;
    
            g2d.setColor(Color.GREEN);
    
            blob.x = (width - blob.width) / 2;
    
            System.out.println(blob);
            g2d.fill(blob);
    
            if (spaceOn) {
                g2d.setFont(UIManager.getFont("Label.font").deriveFont(24f));
                FontMetrics fm = g2d.getFontMetrics();
    
                String spaceIsOn = "Space On";
    
                int x = (width - fm.stringWidth(spaceIsOn)) / 2;
                int y = ((height - fm.getHeight()) / 2) + fm.getAscent();
    
                g2d.drawString(spaceIsOn, x, y);
            }
    
            g2d.dispose();
    
        }
    
        protected class MouseFocusHandler extends MouseAdapter {
    
            @Override
            public void mouseClicked(MouseEvent e) {
                requestFocusInWindow();
            }
    
        }
    
        protected class RepaintAction implements ActionListener {
    
            @Override
            public void actionPerformed(ActionEvent e) {
                yPos += direction;
                blob.y = yPos;
    
                if (blob.y + blob.height > getHeight() - 1) {
                    blob.y = getHeight() - 1 - blob.height;
                    direction = -2;
                } else if (blob.y < 0) {
                    blob.y = 0;
                    direction = 2;
                }
                repaint();
            }
    
        }
    
        protected class SpaceAction extends AbstractAction {
    
            @Override
            public void actionPerformed(ActionEvent e) {
                spaceOn = !spaceOn;
                repaint();
            }
    
        }
    
    }
    

    【讨论】:

    • 我将对此进行测试,如果它比我的解决方案效果更好,那么您将获得一个绿色的复选标记,先生。
    • 嗯,您的解决方案有效,但移动框移动不顺畅。相反,它不规律地闪烁。我会乱来看看能不能让它更顺利,但这在我看来是不能接受的。
    • @NoBrainer 这是键绑定的示例,而不是动画:P
    • @NoBrainer 别忘了,你的问题是关于键绑定,而不是动画;)
    • 触摸。但是,我目前正在将 awt 与 swing 进行比较,看看我想使用哪个。所以动画不是问题的一部分,但它是我目标的一部分。
    猜你喜欢
    • 2013-11-12
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 2017-01-16
    • 1970-01-01
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多