關於組件綁定的事件沒有響應的解決方法

如下面例子講解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 自動生成的方法存根
    }
}
相關文章
相關標籤/搜索