1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.wotonomy.ui.swing.components;
20
21 import java.awt.AWTEventMulticaster;
22 import java.awt.Component;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.awt.event.KeyEvent;
26 import java.awt.event.KeyListener;
27
28 import javax.swing.Timer;
29
30 /***
31 * KeyDelayTimer is a utility that listens for KeyEvents from one
32 * or more components. After receiving a KeyEvents the timer will
33 * broadcast an action event if a specified time interval passes without
34 * a subsequent KeyEvent.<BR><BR>
35 *
36 * This utility is useful for implementing any kind of auto-complete
37 * feature in a user interface.
38 *
39 * @author michael@mpowers.net
40 * @author $Author: cgruber $
41 * @version $Revision: 904 $
42 * $Date: 2006-02-18 23:19:05 +0000 (Sat, 18 Feb 2006) $
43 */
44 public class KeyDelayTimer implements ActionListener, KeyListener
45 {
46
47 protected Timer keyTimer = null;
48 protected Component lastFieldTouched = null;
49 protected long timeLastFieldTouched = 0;
50 protected int interval = 400;
51
52
53 protected ActionListener actionListener = null;
54
55 /***
56 * Default constructor.
57 */
58 public KeyDelayTimer()
59 {
60 keyTimer = new Timer( interval, this );
61 }
62
63 /***
64 * Convenience constructor.
65 * @param listener An action listener to be notified of delay events.
66 */
67 public KeyDelayTimer( ActionListener listener )
68 {
69 this();
70 addActionListener( listener );
71 }
72
73 /***
74 * Returns the last component that generated a KeyEvent.
75 * @return The component that sent the most recent KeyEvent.
76 */
77 public Component getComponent()
78 {
79 return lastFieldTouched;
80 }
81
82 /***
83 * Returns the number of milliseconds before an ActionEvent is generated.
84 * The default is 400.
85 * @return The current delay interval in milliseconds.
86 */
87 public int getInterval()
88 {
89 return interval;
90 }
91
92 /***
93 * Sets the number of milliseconds before an ActionEvent will be generated
94 * after a KeyEvent is received.
95 * @param millis The new delay interval in milliseconds.
96 */
97 public void setInterval( int millis )
98 {
99 interval = millis;
100 keyTimer.setDelay( interval / 2 );
101 }
102
103
104
105 public void keyTyped(KeyEvent e)
106 {
107 }
108 public void keyPressed(KeyEvent e)
109 {
110 }
111
112 /***
113 * Receives key events from one or more components.
114 * Records the component and the time this event was received,
115 * then starts the timer.
116 * @param e The key event in question.
117 */
118 public void keyReleased(KeyEvent e)
119 {
120 if ( ( Character.isLetterOrDigit( e.getKeyChar() ) )
121 || ( e.getKeyCode() == KeyEvent.VK_SPACE )
122 || ( e.getKeyCode() == KeyEvent.VK_DELETE )
123 || ( e.getKeyCode() == KeyEvent.VK_BACK_SPACE ) )
124 {
125 this.lastFieldTouched = e.getComponent();
126 this.timeLastFieldTouched = System.currentTimeMillis();
127 this.keyTimer.start();
128 return;
129 }
130 }
131
132
133
134 /***
135 * Receives ActionEvents from the internal timer.
136 * If the interval has passed without another KeyEvent,
137 * an ActionEvent is broadcast, with the name of this class
138 * as the ActionCommand, and the internal timer is stopped.
139 * @param e The action event in question.
140 */
141 public void actionPerformed(ActionEvent e)
142 {
143 if ( e.getSource() == keyTimer )
144 {
145 if ( System.currentTimeMillis() - this.timeLastFieldTouched > interval )
146 {
147 this.keyTimer.stop();
148 broadcastEvent( new ActionEvent( this, ActionEvent.ACTION_PERFORMED, this.getClass().getName() ) );
149 }
150 return;
151 }
152 }
153
154
155
156 /***
157 * Adds an action listener to the list that will be
158 * notified by button events and changes in button state.
159 * @param l An action listener to be notified.
160 */
161 public void addActionListener(ActionListener l)
162 {
163 actionListener = AWTEventMulticaster.add(actionListener, l);
164 }
165 /***
166 * Removes an action listener from the list that will be
167 * notified by button events and changes in button state.
168 * @param l An action listener to be removed.
169 */
170 public void removeActionListener(ActionListener l)
171 {
172 actionListener = AWTEventMulticaster.remove(actionListener, l);
173 }
174 /***
175 * Notifies all registered action listeners of a pending Action Event.
176 * @param e An action event to be broadcast.
177 */
178 protected void broadcastEvent(ActionEvent e)
179 {
180 if (actionListener != null)
181 {
182 actionListener.actionPerformed(e);
183 }
184 }
185
186 }
187
188