Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在具有许多JTextFields的Java Swing JFrame实例中获取关键事件?_Java_Swing_Events_Awt_Keylistener - Fatal编程技术网

如何在具有许多JTextFields的Java Swing JFrame实例中获取关键事件?

如何在具有许多JTextFields的Java Swing JFrame实例中获取关键事件?,java,swing,events,awt,keylistener,Java,Swing,Events,Awt,Keylistener,我有一个JFrame类,它实现了几个jlabel和JTextFields,我想在焦点在JFrame上并且用户按F1时执行一个操作 我创建了以下类来处理KeyListener: 公共类PropertiesKey实现了KeyListener、ActionListener{ 私人物业窗口; 公共属性密钥(属性p){ 属性窗口=p; System.out.println(“调试属性键”); } @凌驾 按下公共无效键(KeyEvent事件){ System.out.println(“调试键按下”); /

我有一个JFrame类,它实现了几个jlabel和JTextFields,我想在焦点在JFrame上并且用户按F1时执行一个操作

我创建了以下类来处理KeyListener:

公共类PropertiesKey实现了KeyListener、ActionListener{
私人物业窗口;
公共属性密钥(属性p){
属性窗口=p;
System.out.println(“调试属性键”);
}
@凌驾
按下公共无效键(KeyEvent事件){
System.out.println(“调试键按下”);
//F1-显示属性窗口
如果(event.getKeyCode()==KeyEvent.VK_F1){
系统输出打印项次(“F1”);
if(propertiesWindow.isVisible()){
propertiesWindow.setVisible(false);
}否则{
propertiesWindow.setVisible(true);
}
}
System.out.println(“按键”+事件);
}
@凌驾
公共无效密钥已释放(KeyEvent事件){
System.out.println(“按键释放”+事件);
}
@凌驾
public void keyTyped(KeyEvent事件){
System.out.println(“键类型”+事件);
}
@凌驾
已执行的公共无效操作(操作事件){
System.out.println(“执行的操作”+事件);
}
}
我使用以下方法将其附加到主JFrame类:

this.addKeyListener(new PropertiesKey(this));
我确信在创建Key listener类时,当我看到System.out消息时,这实际上是附加的

虽然这种策略在我有AWT框架的程序的另一个区域有效,但在这个JFrame填充了JTextFields的特定情况下,我无法将KeyEvent传播到我的侦听器

我怀疑TextFields(JFrame上的焦点总是被一个TextField捕获)可能正在拦截事件而不是传播它

如果是这样的话,我该怎么解决呢?哪种策略/模式用于在JFrame级别捕获关键事件


事实并非如此,我如何进一步解决此问题?

您不应该使用KeyListener。只能为具有焦点的组件生成关键事件。帧将没有直接焦点,只有添加到帧中的组件

相反,您应该使用
键绑定
。使用键绑定,您可以将
击键
映射到
操作
,即使组件没有焦点。确保使用适当的
InputMap

在这种情况下,如果要为框架添加常规处理程序,可以将键绑定添加到框架的“根窗格”

有关更多信息,请阅读上的Swing教程部分


另请阅读上的部分,了解使用
操作的好处

KeyListener
仅适用于(在大多数情况下)当前关注的组件。如果您将其添加到焦点组件的容器中,以防该组件使用关键事件,那么它也将不起作用。注册键盘操作是处理窗口范围热键的更好方法

下面是一个小例子,说明如何做到这一点:

public class FrameHotkey
{
    public static void main ( final String[] args )
    {
        SwingUtilities.invokeLater ( new Runnable ()
        {
            @Override
            public void run ()
            {
                final JFrame frame = new JFrame ();

                frame.setLayout ( new FlowLayout ( FlowLayout.CENTER, 15, 15 ) );
                frame.add ( new JLabel ( "Field 1:" ) );
                frame.add ( new JTextField ( "Field 1", 15 ) );
                frame.add ( new JLabel ( "Field 2:" ) );
                frame.add ( new JTextField ( "Field 2", 15 ) );

                // Hotkey for the F1 in window
                frame.getRootPane ().registerKeyboardAction ( new ActionListener ()
                {
                    @Override
                    public void actionPerformed ( final ActionEvent e )
                    {
                        JOptionPane.showMessageDialog ( frame, "F1 have been pressed!" );
                    }
                }, KeyStroke.getKeyStroke ( KeyEvent.VK_F1, 0 ), JComponent.WHEN_IN_FOCUSED_WINDOW );

                frame.setDefaultCloseOperation ( WindowConstants.EXIT_ON_CLOSE );
                frame.pack ();
                frame.setLocationRelativeTo ( null );
                frame.setVisible ( true );
            }
        } );
    }
}
请注意,我正在这里注册
JFrame
JRootPane
上的热键,但这通常并不重要,因为条件是
JComponent。当在聚焦窗口中注册热键时,意味着您可以在窗口中的任何组件上注册热键,只要该窗口在系统中聚焦,您就会收到操作事件

或者,如果您的应用程序有一个带有菜单项的
JMenuBar
,这些菜单项将执行您想要的操作,那么您可以为这些菜单项指定加速器,它们将根据指定的热键自行处理该操作


我还建议阅读另一个答案中提供的Swing教程camickr中的文章。

registerKeyboardAction(…)
的API声明:此方法现已过时,请结合使用getActionMap()和getInputMap()对于类似的行为。Mikle和camickr信息都帮助我了解了如何实现这一点。(1-)以促进过时方法的使用。直到现在,我还没有在JavaDoc中注意到它,我想知道为什么在这种情况下它没有标记为
@Deprecated
。无论哪种方式,它都只是一种通过InputMap和ActionMap分配热键的实用方法,而不是直接使用它们。新的Swing Key Binding API设计用于将
操作
绑定到
击键
。该方法将ActionListener包装在一个动作中,以便绑定能够工作。关键是您应该使用ActionAPI,因为它提供了比基本ActionListener更多的功能。应使用当前功能开发应用程序。所有Swing组件都对键绑定使用操作。