| 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 |