2015-11-26 230 views
1

我想寫一個使用Swing組件的實時搜索。我正在使用keyListener來跟蹤輸入。基本上我不希望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

請自己試試看,並告訴我們您的嘗試。 –

回答

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

這正是我所期待的。謝謝! – newbie

0

我猜你想使用與Swing文本分量的KeyListener如一個JTextField(我要猜測,因爲你不告訴或顯示我們)。如果是這樣,那麼最好的解決辦法是不要。對這些組件使用KeyListener可能會混淆組件的功能。取決於您希望在文本完全註冊到文本組件之前還是之後進行偵聽,您最好使用DocumentListener或DocumentFilter。

要獲得更完美的答案,請發佈一個更完整的問題,其中包括您最小的代碼示例和有關您的問題的詳細信息。

+0

我已經添加了一個片段。基本上,這正是你在第一部分描述的內容。你能否詳細說明使用DocumentListener的替代方法? – newbie

+1

閱讀Swing教程[如何撰寫DocumentFilter]一節(http://docs.oracle.com/javase/tutorial/uiswing/events/documentlistener.html)以獲取更多信息和工作示例。基本上,無論何時發生事件,您都會進行搜索。 – camickr

+0

@newbie:也閱讀了使用Swing Timers,因爲這將是您將用於延遲的內容。 –

1

請勿在密鑰或文檔事件中等待,它會阻止程序進一步處理。而是保存當前時間或(重新)在事件中啓動計時器,然後在其他地方執行您的操作。