Java tutorial
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved. Portions Copyrighted 2012 Daniel Huss. * * The contents of this file are subject to the terms of either the GNU General Public License Version 2 only ("GPL") or * the Common Development and Distribution License("CDDL") (collectively, the "License"). You may not use this file * except in compliance with the License. You can obtain a copy of the License at * http://www.netbeans.org/cddl-gplv2.html or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the specific language * governing permissions and limitations under the License. When distributing the software, include this License Header * Notice in each file and include the License file at nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this particular * file as subject to the "Classpath" exception as provided by Sun in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the License Header, with the fields enclosed by * brackets [] replaced by your own identifying information: "Portions Copyrighted [year] [name of copyright owner]" * * Contributor(s): * * The Original Software is NetBeans. The Initial Developer of the Original Software is Sun Microsystems, Inc. Portions * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. * * If you wish your version of this file to be governed by only the CDDL or only the GPL Version 2, indicate your * decision by adding "[Contributor] elects to include this software in this distribution under the [CDDL or GPL Version * 2] license." If you do not indicate a single choice of license, a recipient has the option to distribute your version * of this file under either the CDDL, the GPL Version 2 or to extend the choice of license to its licensees as provided * above. However, if you add GPL Version 2 code and therefore, elected the GPL Version 2 license, then the option * applies only if the new code is made subject to such option by the copyright holder. */ package de.unentscheidbar.validation.swing.trigger; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.IdentityHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import javax.annotation.Nonnegative; import javax.swing.Timer; import com.google.common.base.Equivalence.Wrapper; import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.SetMultimap; import de.unentscheidbar.validation.internal.Beans; import de.unentscheidbar.validation.swing.TriggerEvent; import de.unentscheidbar.validation.swing.TriggerEvent.Listener; final class DelayedTrigger<C> implements Trigger<C>, ActionListener, Listener { private final Trigger<C> other; private final Timer timer; private final Map<Object, TriggerEvent> pendingEvents; private final SetMultimap<Wrapper<Object>, Wrapper<Listener>> observed; DelayedTrigger(@Nonnegative int delay, Trigger<C> other) { Objects.requireNonNull(other, "other"); this.timer = new Timer(delay, this); this.timer.setRepeats(false); this.timer.setCoalesce(false); this.other = other; this.pendingEvents = new IdentityHashMap<>(1); this.observed = LinkedHashMultimap.create(4, 1); } @Override public final void stopObserving(C component, Listener listener) { other.stopObserving(component, this); observed.remove(Beans.identity(component), Beans.identity(listener)); } @Override public final void startObserving(C component, Listener listener) { other.startObserving(component, this); observed.put(Beans.identity((Object) component), Beans.identity(listener)); } @Override public void actionPerformed(ActionEvent e) { synchronized (pendingEvents) { for (Entry<Object, TriggerEvent> entry : pendingEvents.entrySet()) { Wrapper<Object> componentIdentity = Beans.identity(entry.getKey()); for (Wrapper<Listener> listener : observed.get(componentIdentity)) { listener.get().onValidation(entry.getValue()); } } pendingEvents.clear(); } } @Override public void onValidation(TriggerEvent e) { synchronized (pendingEvents) { pendingEvents.put(e.getComponent(), e); } timer.restart(); } }