按下回车键时文本字段中的 KeyListener 未触发

Posted

技术标签:

【中文标题】按下回车键时文本字段中的 KeyListener 未触发【英文标题】:KeyListener in Textfield not firing when press enter 【发布时间】:2012-12-27 21:15:09 【问题描述】:

我正在尝试制作一个可以在 java 中将华氏温度转换为摄氏度的程序。在程序中,我有 2 个标签和 1 个文本字段用于输入。我想在用户输入温度并按 Enter 时转换温度。为此,我在我的文本字段中添加了一个关键侦听器,但它不起作用。当我按 Enter 时,侦听器根本不会触发。

这是我的代码。

public class TempConv extends JFrame

private JLabel info;
private JLabel result;
private JTextField input;
private String outcome;

public TempConv()

    super("Temperature Converter");
    setLayout(new BorderLayout());

    info = new JLabel("Enter Fahrenheit Temperature");
    add(info, BorderLayout.NORTH);

    input = new JTextField(12);
    add(input, BorderLayout.CENTER);

    result  = new JLabel("Temperature in Celcius is: " + outcome);
    add(result, BorderLayout.SOUTH);

    input.addKeyListener(
            new KeyListener()

                public void keyPressed(KeyEvent e)

                    if(e.getKeyChar() == KeyEvent.VK_ENTER)

                        outcome = input.getText();
                           
                
            
        );


public static void main(String[] args) 


    TempConv ftc = new TempConv();
    ftc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    ftc.setLocationRelativeTo(null);
    ftc.setSize(370, 100);
    ftc.setVisible(true);





编辑: 它适用于 ActionListener 但我需要使用匿名类。如果没有匿名类,它会使用 Enter 触发。

【问题讨论】:

该事件在事件链的上游被消耗,因此它永远不会到达您,最好使用Key Bindings - 实际上,最好使用ActionListener 来完成您正在尝试做的事情- 这就是它的设计目的 - 请记住,[Enter] 并不总是每个平台的“接受”键;) 我尝试使用动作监听器。一切都很顺利,直到我找不到如何检查在 ActionListener 中是否按下了 enter 键。 这有关系吗?从独立于平台的角度来看,ActionListener 将在用户触发该平台的“接受”操作时触发。碰巧的是,对于大多数平台,它是 [Enter] 键。 “我错了吗?” 是的……也不是。 KeyListener 是低级 API,用于您想要实现的目标。如果您真的想监视 [Enter] 键,那么您将不得不替换文本字段使用的键绑定开始。然而,这将改变应用程序在其他平台上的工作方式,因此是ActionListener 的原因。这允许外观决定在什么条件下触发ActionListener。在大多数平台下,这就是 [Enter] 键... 嗯.. 我明白你的意思。然后我将专注于 ActionListener。 【参考方案1】:

尝试使用 e.getKeyCode() 代替 e.getKeyChar()。常量 KeyEvent.VK_ENTER 是 int,而不是 char。

换句话说:

if(e.getKeyCode() == KeyEvent.VK_ENTER)
      outcome = input.getText();

而不是

if(e.getKeyChar() == KeyEvent.VK_ENTER)
      outcome = input.getText();

【讨论】:

不错的建议,但是,“当我按下 Enter 时,侦听器根本不会触发” [Enter] 键在事件链的上层被消耗,这意味着永远不会触发侦听器 - [Enter] 开始被文本字段用于其他内容并开始使用 这是真的,尽管我假设他们正在判断监听器是否触发,判断 if 语句是否真的导致输出被打印。也许我不应该做出这样的假设...... 正如我所说,其他方面的建议很好,OP 应该考虑将来考虑,但在这种情况下无济于事,抱歉【参考方案2】:

首先,您需要实现 KeyListener 中的所有方法。你还没有实现 keyTyped 和 keyReleased。另一件事是您应该检查键代码而不是键字符,因为“Enter”字符不可见,因此最好检查键代码是否等于 KeyEvent.VK_ENTER。最后一件事是,当您按 Enter 时,您会更新结果字符串变量,但您不会在任何地方显示它,因此您需要在结果 JLabel 上设置文本。您还忘记了进行转换。我的解释可能令人困惑,但下面是代码:

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

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class TempConv extends JFrame

private JLabel info;
private JLabel result;
private JTextField input;
private String outcome;

public TempConv()

    super("Temperature Converter");
    setLayout(new BorderLayout());

    info = new JLabel("Enter Fahrenheit Temperature");
    add(info, BorderLayout.NORTH);

    input = new JTextField(12);
    add(input, BorderLayout.CENTER);

    result  = new JLabel("Temperature in Celcius is: " + outcome);
    add(result, BorderLayout.SOUTH);

    input.addKeyListener(
            new KeyListener()

                @Override
                public void keyPressed(KeyEvent e)

                    if(e.getKeyCode() == KeyEvent.VK_ENTER)
                        outcome = input.getText();
                        double celsius = (((Double.valueOf(outcome)) - 32) * 5 / 9 );
                        result.setText("Temperature in Celcius is: " + celsius);
                           
                

                @Override
                public void keyTyped(KeyEvent e) 
                    // TODO Auto-generated method stub

                

                @Override
                public void keyReleased(KeyEvent e) 
                    // TODO Auto-generated method stub

                
            
        );


public static void main(String[] args) 


    TempConv ftc = new TempConv();
    ftc.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    ftc.setLocationRelativeTo(null);
    ftc.setSize(370, 100);
    ftc.setVisible(true);





【讨论】:

【参考方案3】:

迟到的答案,但我尝试使用问题中的代码并且 KeyPressed 确实触发了,但是因为 JLabel 没有更新,您假设 KeyEvent 没有被触发。

紧接着

outcome = input.getText(); 

添加

result.setText("Temperature in Celcius is: " + outcome);

因此标签会自行更新。

【讨论】:

【参考方案4】:

按钮不需要KeyListener(大多数情况下不应该使用它们),它们使用ActionListener 来响应所有激活事件,包括Enter、鼠标点击和键盘快捷键,这是一个更加简化的 API。

更多详情请参阅How to Use Buttons, Check Boxes, and Radio Buttons、How to Write an Action Listeners 和How to Use Actions

您还可以将按钮设置为“默认”按钮,该按钮可以在未聚焦时激活(只要当前聚焦的组件不使用/消耗 Enter 键)

请参阅JRootPane#setDefaultButton 和How to Use Root Panes 了解更多详情

【讨论】:

【参考方案5】:

这应该可以工作

if (e.getKeyChar() == 10) 
    System.out.println("enter");
 

输入 ASCII 码为 10 而 KeyEvent.VK_ENTER 为回车返回 13

【讨论】:

以上是关于按下回车键时文本字段中的 KeyListener 未触发的主要内容,如果未能解决你的问题,请参考以下文章

按下 Enter 时将焦点转移到下一个字段

html表单 - 按下回车时自动按钮焦点

检测文本输入字段中的 Enter 键

为啥 KeyListener 仅在未按下按钮时才起作用?

在按钮单击或输入键上发送文本字段输入

觅求高手.java键盘事件.