keylistener等待输入

时间:2015-11-26 15:49:21

标签: java swing

我想使用Swing组件编写实时搜索。我正在使用keyListener来跟踪输入。基本上我不希望每次按下按钮时keyListener采取动作,而是等待(一段时间)更多的输入输入。每次按下按钮时都会刷新该时间段,并在最终超时时评估输入(例如,在该时间段内没有按下按钮意味着输入完成)。如何将其实现到我的keyListener

主要方法的代码段:

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

提前致谢

3 个答案:

答案 0 :(得分:3)

使用DocumentListener或DocumentFilter要好得多,具体取决于您是否要在文本组件完全注册文本之前或之后进行监听。

DocumentListener将在文本发生变化时进行注册,无论是通过按键,复制和粘贴,还是删除文本。然后,定时器将等待您希望对文本执行任何操作的时间。例如:

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

答案 1 :(得分:1)

不要在密钥或文档事件中等待,它只会阻止程序进一步处理。而是保存当前时间或(重新)在事件中启动计时器,并在其他地方执行您的操作。

答案 2 :(得分:0)

我猜你正在尝试将KeyListener与Swing文本组件(如JTextField)一起使用(我必须猜测,因为你不告诉或告诉我们)。如果是这样,那么最好的解决方案是。将KeyListener与这些组件一起使用可能会破坏组件的功能。更好的方法是使用DocumentListener或DocumentFilter,具体取决于您是否要在文本组件完全注册文本之前或之后进行监听。

要获得更完整的答案,请发布更完整的问题,包括最少的代码示例和有关问题的详细信息。