Java 给予JPanel优先关注

Java 给予JPanel优先关注,java,swing,focus,jpanel,keylistener,Java,Swing,Focus,Jpanel,Keylistener,我有一个JPanel,它使用KeyListener作为内容窗格作为窗口;但是,JPanel顶部的网格布局中有按钮和文本字段 如何确定JPanel焦点的优先级,使其在编辑文本或单击按钮后保持焦点,以便我可以读取按键输入?您只需在focusLost事件上添加一个FocusListener,然后再次请求焦点。大概是这样的: import java.awt.*; import java.awt.event.*; import javax.swing.*; public class JPanelFocu

我有一个JPanel,它使用KeyListener作为内容窗格作为窗口;但是,JPanel顶部的网格布局中有按钮和文本字段


如何确定JPanel焦点的优先级,使其在编辑文本或单击按钮后保持焦点,以便我可以读取按键输入?

您只需在
focusLost
事件上添加一个
FocusListener
,然后再次请求焦点。大概是这样的:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class JPanelFocus {
  public static void main(String... argv) throws Exception {
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        JFrame f = new JFrame("FocusTest");
        JButton b = new JButton("Button");
        final JPanel p = new JPanel();
        p.add(b);
        // Here is the KeyListener installed on our JPanel
        p.addKeyListener(new KeyAdapter() {
          public void keyTyped(KeyEvent ev) {
            System.out.println(ev.getKeyChar());
          }
        });
        // This is the bit that does the magic - make sure
        // that our JPanel is always focussed
        p.addFocusListener(new FocusAdapter() {
          public void focusLost(FocusEvent ev) {
            p.requestFocus();
          }
        });
        f.getContentPane().add(p);
        f.pack();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
        // Make sure JPanel starts with the focus
        p.requestFocus();
      }
    });
  }
}

如果您有需要保持焦点的字段(您提到了一个可编辑的文本字段),这将不起作用。关键事件什么时候应该转到文本字段,什么时候应该转到JPanel?

作为替代,您也可以使子组件不可聚焦

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class MyPanel extends JPanel implements KeyListener {
    public MyPanel() {
        this.setFocusable(true);
        this.addKeyListener(this);

        // for each component
        JComboBox<String> comboBox = new JComboBox<String>();
        comboBox.addItem("Item1");
        this.add(comboBox);
        // this is what keeps each child from intercepting KeyEvents
        comboBox.setFocusable(false);
    }

    public void keyPressed(KeyEvent e) { ... }
    public void keyTyped(KeyEvent e) { ... }
    public void keyReleased(KeyEvent e) { ... }

    public static void main(String[] args) {
        // create a frame
        JFrame frame = new JFrame();
        frame.setSize(640, 480);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // add MyPanel to frame
        MyPanel panel = new MyPanel();
        frame.add(panel);
        frame.setVisible(true);
    }
}
import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
类MyPanel扩展JPanel实现KeyListener{
公共事务委员会(){
此参数为.setFocusable(true);
this.addKeyListener(this);
//对于每个组件
JComboBox comboBox=新的JComboBox();
comboBox.addItem(“项目1”);
这个.add(组合框);
//这就是阻止每个孩子截取关键事件的原因
comboBox.setFocusable(假);
}
public void键按下(KeyEvent e){…}
public void keyTyped(KeyEvent e){…}
public void keyReleased(KeyEvent e){…}
公共静态void main(字符串[]args){
//创建一个框架
JFrame=新JFrame();
帧设置大小(640480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//将MyPanel添加到框架
MyPanel=新的MyPanel();
框架。添加(面板);
frame.setVisible(true);
}
}