Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!.POSTED!not-for-mail From: Steven Simpson Newsgroups: comp.lang.java.programmer Subject: Re: Lightweight postDelayed / removeCallbacks Date: Sun, 05 Feb 2012 22:00:50 +0000 Organization: Aioe.org NNTP Server Lines: 79 Message-ID: References: NNTP-Posting-Host: SYma/1Oij9bhI+errvtPhg.user.speranza.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:9.0) Gecko/20111229 Thunderbird/9.0 X-Notice: Filtered by postfilter v. 0.8.2 Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:11750 On 04/02/12 19:44, Jan Burse wrote: > postDelayed(Runnable r, int d): > Posts an event on the EDT, which will > invoked r after a delay of d millisecond. > > removeCallbacks(Runnable r): > Immediately remove all events from the > EDT that would invoke r. > > One could use javax.swing.Timer for the first > method. Something along: > > public void postDelayed(final Runnable r, int d) { > final Timer t=new Timer(d,new ActionListener() { > public void actionPerformed(ActionEvent e) { > r.run(); > } > }); > t.setRepeats(false); > t.start(); > } > > But then for the second method one would need to > track the created timers, so as to be able to > selectively stop them. A first stab: Keep a WeakHashMap>>, making all changes on the EDT. Store weak references to each created Timer, in a HashSet per Runnable. When asked to remove all callbacks, remove the Runnable from the map, get its Collection of Timers, and stop them. If the references have already expired, you don't care. When all the Timers using the same Runnable have expired, assuming that they naturally decay, the map entry will be removed anyway. // uncompiled void removeCallbacks(final Runnable r) { invokeAndWait(new Runnable() { public void run() { Collection> timers = map.remove(r); if (timers == null) return; for (Reference rt : timers) { Timer t = rt.get(); if (t != null) t.stop(); } } }); } void postDelayed(final Runnable r, int d) { final Timer t=new Timer(d,new ActionListener() { public void actionPerformed(ActionEvent e) { r.run(); } }); invokeAndWait(new Runnable() { public void run() { Collection> coll = map.get(r); if (coll == null) { coll = new HashSet>(); map.put(r, coll); } coll.add(new WeakReference(t)); } }); // should use d too! t.setRepeats(false); t.start(); } -- ss at comp dot lancs dot ac dot uk