001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package javax.swing;
018:
019: import java.awt.event.ActionEvent;
020: import java.awt.event.ActionListener;
021: import java.io.Serializable;
022: import java.util.TimerTask;
023:
024: import javax.swing.event.EventListenerList;
025:
026: import org.apache.harmony.x.swing.internal.nls.Messages;
027:
028: /**
029: * <p>
030: * <i>Timer</i>
031: * </p>
032: * <h3>Implementation Notes:</h3>
033: * <ul>
034: * <li>The <code>serialVersionUID</code> fields are explicitly declared as a performance
035: * optimization, not as a guarantee of serialization compatibility.</li>
036: * </ul>
037: */
038: public class Timer implements Serializable {
039:
040: private class FiringEventRunnable implements Runnable {
041: private ActionEvent event;
042: private int queuedCounter;
043:
044: public synchronized void preQueueInit(final long scheduledTime) {
045: queuedCounter++;
046: event = new ActionEvent(Timer.this , 0, null, scheduledTime,
047: 0);
048: }
049:
050: public synchronized boolean isQueued() {
051: return queuedCounter > 0;
052: }
053:
054: public synchronized void run() {
055: if (getLogTimers()) {
056: System.out.println("Timer ringing: " + Timer.this );
057: }
058: fireActionPerformed(event);
059: if (isRepeats) {
060: queuedCounter--;
061: } else {
062: stopImpl();
063: }
064: }
065: }
066:
067: protected EventListenerList listenerList = new EventListenerList();
068:
069: /**
070: * following fields purposes fully corresponds to their names
071: */
072: private int delay;
073: private int initialDelay;
074: private boolean isRepeats = true;
075: private boolean isCoalesce = true;
076: private TimerTask timerTask;
077:
078: private static final long serialVersionUID = 3624204224649954546L;
079:
080: /**
081: * this thread is used to execute all timers
082: */
083: private static java.util.Timer timerThread;
084:
085: /**
086: * this value indicates whether we need to make output about every ringing
087: * timer
088: */
089: private static boolean isLogTimers;
090:
091: public Timer(final int delay, final ActionListener listener) {
092: this .delay = delay;
093: initialDelay = delay;
094: addActionListener(listener);
095: }
096:
097: public void setRepeats(final boolean isRepeats) {
098: this .isRepeats = isRepeats;
099: }
100:
101: public boolean isRepeats() {
102: return isRepeats;
103: }
104:
105: public void setCoalesce(final boolean isCoalesce) {
106: this .isCoalesce = isCoalesce;
107: }
108:
109: public boolean isCoalesce() {
110: return isCoalesce;
111: }
112:
113: public void setInitialDelay(final int initialDelay) {
114: if (initialDelay < 0) {
115: throw new IllegalArgumentException(Messages.getString(
116: "swing.63", initialDelay)); //$NON-NLS-1$
117: }
118: this .initialDelay = initialDelay;
119: }
120:
121: public int getInitialDelay() {
122: return initialDelay;
123: }
124:
125: public void setDelay(final int delay) {
126: if (delay < 0) {
127: throw new IllegalArgumentException(Messages.getString(
128: "swing.64", delay)); //$NON-NLS-1$
129: }
130: this .delay = delay;
131: }
132:
133: public int getDelay() {
134: return delay;
135: }
136:
137: public void start() {
138: if (isRunning()) {
139: return;
140: }
141:
142: if (timerThread == null) {
143: timerThread = new java.util.Timer(true);
144: }
145: timerTask = createTimerTask();
146: timerThread
147: .scheduleAtFixedRate(timerTask,
148: getPositiveDelay(initialDelay),
149: getPositiveDelay(delay));
150: }
151:
152: public void stop() {
153: stopImpl();
154: }
155:
156: public void restart() {
157: stop();
158: start();
159: }
160:
161: public boolean isRunning() {
162: return (timerTask != null);
163: }
164:
165: public <T extends java.util.EventListener> T[] getListeners(
166: final Class<T> listenersClass) {
167: return listenerList.getListeners(listenersClass);
168: }
169:
170: public void removeActionListener(final ActionListener listener) {
171: listenerList.remove(ActionListener.class, listener);
172: }
173:
174: public void addActionListener(final ActionListener listener) {
175: listenerList.add(ActionListener.class, listener);
176: }
177:
178: public ActionListener[] getActionListeners() {
179: return listenerList.getListeners(ActionListener.class);
180: }
181:
182: protected void fireActionPerformed(final ActionEvent event) {
183: final ActionListener[] listeners = getActionListeners();
184: for (int i = 0; i < listeners.length; i++) {
185: listeners[i].actionPerformed(event);
186: }
187: }
188:
189: public static void setLogTimers(final boolean isLogTimers) {
190: Timer.isLogTimers = isLogTimers;
191: }
192:
193: public static boolean getLogTimers() {
194: return isLogTimers;
195: }
196:
197: private void stopImpl() {
198: if (timerTask != null) {
199: timerTask.cancel();
200: timerTask = null;
201: }
202: }
203:
204: private TimerTask createTimerTask() {
205: return new TimerTask() {
206: private final FiringEventRunnable fireEvent = new FiringEventRunnable();
207:
208: @Override
209: public void run() {
210: if (!isCoalesce || !fireEvent.isQueued()) {
211: fireEvent.preQueueInit(scheduledExecutionTime());
212: SwingUtilities.invokeLater(fireEvent);
213: }
214: }
215: };
216: }
217:
218: private static int getPositiveDelay(final int d) {
219: return (d > 0) ? d : 1;
220: }
221: }
|