首页 > 解决方案 > 当您添加带有按钮的 JPanel 时,为什么 KeyListener 不会收到事件?

问题描述

我有以下 Java swing 应用程序:

KeyListener 测试应用

它包括:

如果我不包括按钮,KeyListener 工作,我按下一个键,我会在输出窗口中看到键码。但是一旦我添加了 Buttons 类,关键事件就不再显示在输出窗口中。

为什么?

主要功能如下:

package testkeyboard;

public class TestKeyboard {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        
        Window w = new Window();
        w.setVisible(true);
        
    }
    
}

窗口类如下:

package testkeyboard;

import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Window extends JFrame {
    
    Buttons buttons;
    JPanel panel1;
    JPanel panel2;
    
    public Window() {

        buttons = new Buttons();
        panel1 = new JPanel();
        panel1.setBackground(Color.red);
        panel2 = new JPanel();
        panel2.setBackground(Color.green);
        
        this.setSize(640, 480);
        this.getContentPane().add(buttons, BorderLayout.NORTH);   
        this.getContentPane().add(panel1, BorderLayout.CENTER);   
        this.getContentPane().add(panel2, BorderLayout.SOUTH);   
        
        this.addKeyListener(new KeyboardHandler());
    }
    

}

实现 KeyListener 的类如下:

package testkeyboard;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class KeyboardHandler implements KeyListener {

    @Override
    public void keyPressed(KeyEvent event) {
        System.out.println("KEYCODE: " + event.getKeyCode());
    }
    
    @Override
    public void keyReleased(KeyEvent event) {
        //printEventInfo("Key Released", event);
    }
    @Override
    public void keyTyped(KeyEvent event) {
        //printEventInfo("Key Typed", event);
    }

}

带有按钮的类如下:

package testkeyboard;

import java.awt.BasicStroke;
import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import javax.swing.JPanel;

public class Buttons extends JPanel implements ActionListener {
    
            
    private Button button1;
    private Button button2;
    private Button button3;
    
    public Buttons() {
        
        button1 = new Button("B1");
        button2 = new Button("B2");
        button3 = new Button("B3");
        
        button1.addActionListener((ActionListener) this); 
        button2.addActionListener((ActionListener) this); 
        button3.addActionListener((ActionListener) this); 
        
        this.add(button1);
        this.add(button2);
        this.add(button3);
        
        this.setBackground(Color.blue);
        this.setForeground(Color.white);

        this.setLayout(new FlowLayout(FlowLayout.LEFT));                  
                
    }    
            
    public void actionPerformed(ActionEvent event) {
        
        Object source = event.getSource();
        if (source.equals(button1)) {
            System.out.println("BUTTON 1 CLICK");
        }
        else if (source.equals(button2)) {
            System.out.println("BUTTON 2 CLICK");
        }
        else if (source.equals(button3)) {
            System.out.println("BUTTON 3 CLICK");
        }        

    }
        
}

编辑:问题已被标记为重复,SO 问题指出处理 a KeyListenerin a JPanel,而这个问题处理 a KeyListenerin a JFrame。它也缺乏一个完整的例子。

因此,如果它可能对其他人有用,我会包含类代码,包括在这种情况下Window如何使用:KeyBindings

public class Window extends JFrame {
    
    Buttons buttons;
    JPanel panel1;
    JPanel panel2;
    
    public Window() {

        buttons = new Buttons();
        panel1 = new JPanel();
        panel1.setBackground(Color.red);
        panel2 = new JPanel();
        panel2.setBackground(Color.green);
        
        this.setSize(640, 480);
        this.getContentPane().add(buttons, BorderLayout.NORTH);   
        this.getContentPane().add(panel1, BorderLayout.CENTER);   
        this.getContentPane().add(panel2, BorderLayout.SOUTH);   
        
        this.addKeyListener(new KeyboardHandler());
        
        InputMap iMap = ((JComponent)(this.getContentPane())).getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap aMap = ((JComponent)(this.getContentPane())).getActionMap();
        
        iMap.put(KeyStroke.getKeyStroke("F2"), "doSomething");
        aMap.put("doSomething", doSomething);
    };
        
    Action doSomething = new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("actionPerformed!");
        }
    };

}

标签: javaswingawtkeylistener

解决方案


推荐阅读