简体   繁体   English

侦听器等待输入

[英]keylistener wait for input

I want to write a live search using Swing components. 我想使用Swing组件编写实时搜索。 I am using a keyListener to keep track of the input. 我正在使用keyListener来跟踪输入。 Basically i dont want the keyListener to take action every time a button is pressed but instead wait (for some period of time) for more incoming input. 基本上,我不希望keyListener每次按下按钮时都采取措施,而是等待(一段时间)以获取更多输入。 This period of time is refreshed every time a button is pressed and the input gets evaluated when it eventually times out (eg no button is being pressed within the period meaning that the input is complete). 每次按下按钮都会刷新此时间段,并在最终超时时评估输入(例如,在此时间内未按下任何按钮表示输入已完成)。 How do I implement that into my keyListener ? 如何在我的keyListener实现它?

Code snippet of main method: 主要方法的代码段:

static JTextField nameTextField = new JTextField();

public static void main(String args[]) throws Exception {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.add(nameTextField, BorderLayout.NORTH);

    nameTextField.addKeyListener(new KeyListener() {

        public void keyTyped(KeyEvent keyEvent) {
            //
        }

        @Override
        public void keyPressed(KeyEvent e) {
            //
        }

        @Override
        public void keyReleased(KeyEvent e) {
                   if(waitForMoreInput(50)) {
                       doSomething(nameTextField.getText());
                   }
                }
            }
        }
    }
    );


    frame.setSize(250, 100);
    frame.setVisible(true);
}

Thanks in advance 提前致谢

Much better is for you to use a DocumentListener or DocumentFilter, depending on if you want to listen before or after text has been fully registered with the text component. 更好的方法是使用DocumentListener或DocumentFilter,这取决于您是否要在文本完全注册到文本组件之前或之后进行监听。

The DocumentListener will register any time the text has changed, be it via a key press, via a copy and paste, via a deletion of text. 文本更改的任何时候,DocumentListener都会注册,无论是通过按键,复制和粘贴,还是删除文本。 The Timer will then wait however long you wish to do whatever action is required on the text. 然后,无论您希望对文本执行任何所需的操作,计时器都将等待。 For example: 例如:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class DocListenerFoo extends JPanel {
    private JTextField nameTextField = new JTextField(20);

    public DocListenerFoo() {
        add(new JLabel("Add Text:"));
        add(nameTextField);

        int timerDelay = 1000; // one second
        nameTextField.getDocument().addDocumentListener(new MyDocListener(timerDelay));
    }

    private class MyDocListener implements DocumentListener {
        private Timer docTimer;
        private int timerDelay;

        public MyDocListener(int timerDelay) {
            this.timerDelay = timerDelay;
        }

        @Override
        public void changedUpdate(DocumentEvent e) {
            textChangedAction(e);
        }

        @Override
        public void insertUpdate(DocumentEvent e) {
            textChangedAction(e);
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            textChangedAction(e);
        }

        private void textChangedAction(DocumentEvent e) {
            Document doc = e.getDocument();
            try {
                String text = doc.getText(0, doc.getLength());
                if (docTimer != null && docTimer.isRunning()) {
                    docTimer.stop();
                }

                docTimer = new Timer(timerDelay, new TimerListener(text));
                docTimer.setRepeats(false);
                docTimer.start();
            } catch (BadLocationException e1) {
                e1.printStackTrace();
            }
        }

    }

    private class TimerListener implements ActionListener {

        private String text;

        public TimerListener(String text) {
            this.text = text;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO do check on text here 
            System.out.println("Checking text here: " + text);
        }

    }

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

        JFrame frame = new JFrame("DocListenerFoo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

Don't wait inside the key or document event, it just blocks the program from being processed further. 不要在键或文档事件中等待,它只是阻止程序被进一步处理。 Instead save the current time or (re)start a timer in the event and execute your action later somewhere else. 而是保存当前时间或在事件中(重新)启动计时器,然后在其他地方执行操作。

I'm guessing that you're trying to use a KeyListener with a Swing text component such as a JTextField (I have to guess since you don't tell or show us). 我猜您正在尝试将KeyListener与Swing文本组件(例如JTextField)一起使用(我不得不猜测,因为您不告诉我们或不告诉我们)。 If so, then the best solution is don't . 如果是这样,那么最好的办法就是不要 Using a KeyListener with these components can mess up the functionality of the components. 在这些组件上使用KeyListener可能会弄乱组件的功能。 Much better is for you to use a DocumentListener or DocumentFilter, depending on if you want to listen before or after text has been fully registered with the text component. 更好的方法是使用DocumentListener或DocumentFilter,这取决于您是否要在文本完全注册到文本组件之前或之后进行监听。

For a better more complete answer, post a better more complete question, including your minimal code example and details about your problem. 为了获得更好,更完整的答案,请发布更好,更完整的问题,包括最小的代码示例和有关问题的详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM