【问题标题】:Use KeyListener in a loop在循环中使用 KeyListener
【发布时间】:2023-03-19 18:28:01
【问题描述】:

我没有很多使用 KeyListeners 的经验,但我在我的应用程序中使用过它,它工作正常,只是我需要等待输入才能继续我的程序。为此,我做了一个 while 循环,循环直到 String temp 不为空(这意味着会有输入)。

问题是无法输入 JTextField(称为输入)。下面是我的两种方法的代码,它们应该一起工作,以便可以返回我的 JTextField(输入)中的文本(作为临时)。我不确定为什么这不起作用或如何解决它。

我的 KeyListener 的 keyPressed 方法:

 public void keyPressed(KeyEvent e)
{
    //only sends text if the enter key is pressed
    if (e.getKeyCode()==KeyEvent.VK_ENTER)
    {
        //if there really is text
        if (!input.getText().equals(""))
        {
            //String temp is changed from null to input
            temp=input.getText();
            //text sent to another JTextField
            output.append(temp+"\n");
            //input no longer has text
            input.setText("");
        }
    }
}

试图获取文本的方法,也在我的 KeyListener 类中

public String getTemp()
{
    booleans isNull=temp==null; 
    //loops until temp is not null
    while (isNull)
    {
        //unnecessary line of code, only used so the loop not empty
        isNull=checkTemp();
    }   
    return temp;
}
public boolean checkTemp()
{
    return temp==null;
}

【问题讨论】:

  • 它正在使用swing
  • 为什么不使用对话框来获取用户的输入?此外,您可以在输入字段上注册一个侦听器。
  • 它基本上就像一个聊天机器人,所以我认为这会显着改变感觉,
  • 摆脱所有这些代码,而是将 ActionListener 添加到 JTextField。
  • 这就是 keyListener 已经存在的地方

标签: java swing while-loop keylistener


【解决方案1】:

您的 while 循环是一个常见的控制台程序构造,但请理解您在这里创建的不是控制台程序,而是一个 事件驱动 GUI,在这种情况下,while 循环与Swing GUI 库,你需要摆脱它。您现在想要响应事件,而不是持续轮询的 while 循环,如果您正在侦听 JTextField 中的用户输入不要使用 KeyListener,因为此低级侦听器可能会导致不需要的一面效果。而是将 DocumentListener 添加到 JTextField 的 Document。

编辑:您正在监听 enter 键,因此解决方案更加简单:将 ActionListener 添加到 JTextField!

例如,

input.addActionListener(e -> {
    String text = input.getText().trim();
    if (text.isEmpty()) {
        return;
    }
    output.append(text + "\n");

    input.setText("");
});

更完整的例子:

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

public class ChatBox extends JPanel {
    private static final int COLS = 40;
    private JTextField input = new JTextField(COLS);
    private JTextArea output = new JTextArea(20, COLS);
    private JButton submitButton = new JButton("Submit");

    public ChatBox() {
        output.setFocusable(false); // user can't get into output
        JScrollPane scrollPane = new JScrollPane(output);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        ActionListener inputListener = e -> {
            String text = input.getText().trim();
            if (text.isEmpty()) {
                return;
            }
            output.append(text + "\n");

            input.setText("");
            input.requestFocusInWindow();
        };

        input.addActionListener(inputListener);
        submitButton.addActionListener(inputListener);

        JPanel bottomPanel = new JPanel();
        bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.LINE_AXIS));
        bottomPanel.add(input);
        bottomPanel.add(submitButton);

        setLayout(new BorderLayout());
        add(scrollPane, BorderLayout.CENTER);
        add(bottomPanel, BorderLayout.PAGE_END);
    }

    private static void createAndShowGui() {
        ChatBox mainPanel = new ChatBox();

        JFrame frame = new JFrame("Chat Box");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

【讨论】:

  • 感谢您提供真正深入的回答,我理解为什么在这种情况下使用 actionListener 比使用 keyListener 更好,但在过去的一个小时里,我无法弄清楚如何让我的代码响应以正确的方式发生事件,因为没有while循环,不考虑actonListener,而是按原样返回temp(null)
  • @BenCarlisle:while 循环不应该在那里。只需摆脱它并将其从您的想法中消除即可。每当你想在 GUI 中使用 while 循环进行连续轮询时,试着对自己说,“我怎样才能通过监听事件来做到这一点?”。至于 KeyListener 的使用,这会扰乱 JTextField 和其他文本组件的内部工作,应该避免。例如,它们可能会扰乱这些组件的选项卡功能,并因复制和粘贴文本而失败。
  • @BenCarlisle: 并且 getTemp 应该从 ActionListener 或其他类似的侦听器中调用。再次响应事件。
猜你喜欢
  • 2013-03-23
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 2012-05-23
  • 1970-01-01
  • 1970-01-01
  • 2020-07-06
  • 2015-07-04
相关资源
最近更新 更多