Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
KeyDelayTimer |
|
| 1.3333333333333333;1.333 |
1 | /* |
|
2 | Wotonomy: OpenStep design patterns for pure Java applications. |
|
3 | Copyright (C) 2000 Blacksmith, Inc. |
|
4 | ||
5 | This library is free software; you can redistribute it and/or |
|
6 | modify it under the terms of the GNU Lesser General Public |
|
7 | License as published by the Free Software Foundation; either |
|
8 | version 2.1 of the License, or (at your option) any later version. |
|
9 | ||
10 | This library is distributed in the hope that it will be useful, |
|
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 | Lesser General Public License for more details. |
|
14 | ||
15 | You should have received a copy of the GNU Lesser General Public |
|
16 | License along with this library; if not, see http://www.gnu.org |
|
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 | // delay timer for keypress-sensitve events |
|
47 | 0 | protected Timer keyTimer = null; |
48 | 0 | protected Component lastFieldTouched = null; |
49 | 0 | protected long timeLastFieldTouched = 0; |
50 | 0 | protected int interval = 400; // adjust as needed |
51 | ||
52 | // for action multicasting |
|
53 | 0 | protected ActionListener actionListener = null; |
54 | ||
55 | /** |
|
56 | * Default constructor. |
|
57 | */ |
|
58 | 0 | public KeyDelayTimer() |
59 | 0 | { |
60 | 0 | keyTimer = new Timer( interval, this ); |
61 | 0 | } |
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 | 0 | this(); |
70 | 0 | addActionListener( listener ); |
71 | 0 | } |
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 | 0 | 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 | 0 | 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 | 0 | interval = millis; |
100 | 0 | keyTimer.setDelay( interval / 2 ); |
101 | 0 | } |
102 | ||
103 | // interface KeyListener |
|
104 | ||
105 | public void keyTyped(KeyEvent e) |
|
106 | { |
|
107 | 0 | } |
108 | public void keyPressed(KeyEvent e) |
|
109 | { |
|
110 | 0 | } |
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 | { // handles keystrokes in the textfields (except ENTER and ESCAPE) |
|
120 | 0 | if ( ( Character.isLetterOrDigit( e.getKeyChar() ) ) |
121 | 0 | || ( e.getKeyCode() == KeyEvent.VK_SPACE ) |
122 | 0 | || ( e.getKeyCode() == KeyEvent.VK_DELETE ) |
123 | 0 | || ( e.getKeyCode() == KeyEvent.VK_BACK_SPACE ) ) |
124 | { |
|
125 | 0 | this.lastFieldTouched = e.getComponent(); |
126 | 0 | this.timeLastFieldTouched = System.currentTimeMillis(); |
127 | 0 | this.keyTimer.start(); |
128 | 0 | return; |
129 | } |
|
130 | 0 | } |
131 | ||
132 | // interface ActionListener |
|
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 | 0 | if ( e.getSource() == keyTimer ) |
144 | { |
|
145 | 0 | if ( System.currentTimeMillis() - this.timeLastFieldTouched > interval ) |
146 | { |
|
147 | 0 | this.keyTimer.stop(); |
148 | 0 | broadcastEvent( new ActionEvent( this, ActionEvent.ACTION_PERFORMED, this.getClass().getName() ) ); |
149 | } |
|
150 | 0 | return; |
151 | } |
|
152 | 0 | } |
153 | ||
154 | // Action Multicast methods |
|
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 | 0 | actionListener = AWTEventMulticaster.add(actionListener, l); |
164 | 0 | } |
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 | 0 | actionListener = AWTEventMulticaster.remove(actionListener, l); |
173 | 0 | } |
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 | 0 | if (actionListener != null) |
181 | { |
|
182 | 0 | actionListener.actionPerformed(e); |
183 | } |
|
184 | 0 | } |
185 | ||
186 | } |
|
187 | ||
188 |