Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.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
Java 在循环中使用KeyListener_Java_Swing_While Loop_Keylistener - Fatal编程技术网

Java 在循环中使用KeyListener

Java 在循环中使用KeyListener,java,swing,while-loop,keylistener,Java,Swing,While Loop,Keylistener,我没有很多使用KeyListener的经验,但我在应用程序中使用了一个,它运行良好,只是我需要等待输入,然后我的程序才能继续。为此,我做了一个while循环,循环直到字符串temp不为null,这意味着将有输入 问题是没有办法输入名为input的JTextField。下面是我的两个方法的代码,它们应该一起工作,以便JTextField输入中的文本可以作为temp返回。我不知道这为什么不起作用,也不知道如何修复它 my KeyListener的按键方法: public void keyPress

我没有很多使用KeyListener的经验,但我在应用程序中使用了一个,它运行良好,只是我需要等待输入,然后我的程序才能继续。为此,我做了一个while循环,循环直到字符串temp不为null,这意味着将有输入

问题是没有办法输入名为input的JTextField。下面是我的两个方法的代码,它们应该一起工作,以便JTextField输入中的文本可以作为temp返回。我不知道这为什么不起作用,也不知道如何修复它

my KeyListener的按键方法:

 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;
}

您的while循环是一个常见的控制台程序构造,但是请理解,您在这里创建的不是控制台程序,而是一个事件驱动的GUI,在这种情况下,while循环会与Swing GUI库发生冲突,您需要摆脱它。现在,您希望响应事件,而不是通过持续轮询进行while循环,并且如果您正在侦听JTextField中的用户输入,请不要使用KeyListener,因为这种低级侦听器可能会导致不必要的副作用。而是将DocumentListener添加到JTextField的文档中

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

e、 g

更完整的示例:

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());
    }
}

它使用swingWhy不使用对话框获取用户的输入?另外,你可以在你的输入栏上注册一个监听器。它基本上就像一个聊天机器人,所以我认为这会显著改变你的感觉,摆脱所有这些代码,而是在JTextField中添加一个ActionListener。这就是keyListener已经想到的地方。感谢您的深入回答,我理解为什么在这种情况下使用ActionListener比使用keyListener更好,但在过去的一个小时里,我还没有弄清楚如何让我的代码响应JTextField中的事件正确的方法是,如果没有while循环,则不会考虑actonListener,而是按原样返回tempnull@BenCarlisle:while循环不应该在那里。把它扔掉,从你的思想中驱逐出去。每当您想在GUI中使用while循环进行连续轮询时,请试着对自己说,我如何通过监听事件来实现这一点?。至于使用KeyListener,这可能会扰乱JTextField和其他文本组件的内部工作,应该避免。例如,它们可能会扰乱这些组件的制表功能,导致文本复制和粘贴失败。@BenCarlisle:并且应该从ActionListener或其他类似的侦听器中调用getTemp。再一次,对事件做出反应。
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());
    }
}