关于组件绑定的事件没有响应的解决方法

如下面例子讲解java

 

下面代码,没有添加按钮的时候,绑定keyListener事件的myframe能够正常得到键盘事件,代码以下:ide

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class Test extends JFrame implements KeyListener {
    public Test() {
        setLayout(new FlowLayout());
        addKeyListener(this);
    }
    public static void main(String[] args) {
                Test myframe = new Test();
                myframe.setSize(400, 300);
                myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                myframe.setVisible(true);                
    }
    @Override
    public void keyPressed(KeyEvent event) {
        // TODO 自动生成的方法存根
        switch (event.getKeyCode()) {
        case KeyEvent.VK_UP:
            System.out.println("up");
            break;
        case KeyEvent.VK_DOWN:
            System.out.println("down");
            break;
        case KeyEvent.VK_LEFT:
            System.out.println("left");
            break;
        case KeyEvent.VK_RIGHT:
            System.out.println("right");
            break;
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {
        // TODO 自动生成的方法存根    
    }
    @Override
    public void keyTyped(KeyEvent e) {
        // TODO 自动生成的方法存根
    }
}

可是当添加按钮btn以后, 绑定keyListener事件的myframe没法得到键盘事件,代码以下:this

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class Test extends JFrame implements KeyListener {
    JButton btn=new JButton("button");
    
    public Test() {
        setLayout(new FlowLayout());
        getContentPane().add(btn);
        addKeyListener(this);
    }
    public static void main(String[] args) {
                Test myframe = new Test();
                myframe.setSize(400, 300);
                myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                myframe.setVisible(true);                
    }
    @Override
    public void keyPressed(KeyEvent event) {
        // TODO 自动生成的方法存根
        switch (event.getKeyCode()) {
        case KeyEvent.VK_UP:
            System.out.println("up");
            break;
        case KeyEvent.VK_DOWN:
            System.out.println("down");
            break;
        case KeyEvent.VK_LEFT:
            System.out.println("left");
            break;
        case KeyEvent.VK_RIGHT:
            System.out.println("right");
            break;
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {
        // TODO 自动生成的方法存根    
    }
    @Override
    public void keyTyped(KeyEvent e) {
        // TODO 自动生成的方法存根
    }
}

经过谷歌查找后才知道spa

添加button后,焦点在button上了,而不是在myframe上code

绑定keyListener事件的myframe要能正常得到键盘事件,myframe必需要获到焦点事件

查询API知在frame显示后调用requestFocus()便可获得焦点开发

public void requestFocus()请求此 Component 获取输入焦点,而且此 Component 的顶层祖先成为得到焦点的 Window。此 Component 对于所要许可的请求而言必须是不可显示的、可聚焦的和可见的而且其全部祖先(除了顶层 Window 之外)必须是可见的。此方法会尽力完成该请求;可是在某些状况下可能没法完成。在此 Component 接收 FOCUS_GAINED 事件前,开发人员永远不能假定此 Component 是焦点全部者。若是因为此 Component 的顶层 Window 没有成为得到焦点的窗口而拒绝了此请求,则记住此请求,并在后来用户使窗口成为得到焦点的窗口时许可此请求。 get

此方法不能用于为根本不是 Component 的内容设置焦点全部者,应该使用 KeyboardFocusManager.clearGlobalFocusOwner()。 it

由于此方法的焦点行为与平台有关,因此强烈建议开发人员在可能时使用 requestFocusInWindow。 io

注:并非全部的焦点传输都将致使防止调用此方法。一样地,组件能够在没有调用此方法或 Component 的其余任何方法的状况下接收焦点。

附参考代码

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class Test extends JFrame implements KeyListener {
    JButton btn=new JButton("button");
    
    public Test() {
        setLayout(new FlowLayout());
        getContentPane().add(btn);
        addKeyListener(this);
    }
    public static void main(String[] args) {
                Test myframe = new Test();
                myframe.setSize(400, 300);
                myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                myframe.setVisible(true);
                myframe.requestFocus();
    }

    @Override
    public void keyPressed(KeyEvent event) {
        // TODO 自动生成的方法存根
        switch (event.getKeyCode()) {
        case KeyEvent.VK_UP:
            System.out.println("up");
            break;
        case KeyEvent.VK_DOWN:
            System.out.println("down");
            break;
        case KeyEvent.VK_LEFT:
            System.out.println("left");
            break;
        case KeyEvent.VK_RIGHT:
            System.out.println("right");
            break;
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {
        // TODO 自动生成的方法存根    
    }
    @Override
    public void keyTyped(KeyEvent e) {
        // TODO 自动生成的方法存根
    }
}
相关文章
相关标签/搜索