001    /*
002     * Created on Mar 29, 2008
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
005     * the License. You may obtain a copy of the License at
006     *
007     * http://www.apache.org/licenses/LICENSE-2.0
008     *
009     * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
010     * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
011     * specific language governing permissions and limitations under the License.
012     *
013     * Copyright @2008-2010 the original author or authors.
014     */
015    package org.fest.swing.input;
016    
017    import static org.fest.swing.listener.WeakEventListener.attachAsWeakEventListener;
018    
019    import java.awt.AWTEvent;
020    import java.awt.Toolkit;
021    import java.awt.event.AWTEventListener;
022    
023    import org.fest.swing.listener.WeakEventListener;
024    import org.fest.util.VisibleForTesting;
025    
026    /**
027     * Understands an <code>{@link AWTEventListener}</code> which normalizes the event stream by sending a single
028     * <code>WINDOW_CLOSED</code>, instead of one every time dispose is called.
029     *
030     * @author Alex Ruiz
031     */
032    public class EventNormalizer implements AWTEventListener {
033    
034      private final DisposedWindowMonitor disposedWindowMonitor;
035    
036      private WeakEventListener weakEventListener;
037      private AWTEventListener listener;
038    
039      /**
040       * Creates a new </code>{@link EventNormalizer}</code>.
041       */
042      public EventNormalizer() {
043        this(new DisposedWindowMonitor());
044      }
045    
046      @VisibleForTesting
047      EventNormalizer(DisposedWindowMonitor disposedWindowMonitor) {
048        this.disposedWindowMonitor = disposedWindowMonitor;
049      }
050    
051      /**
052       * Starts listening for events.
053       * @param toolkit the <code>Toolkit</code> to use.
054       * @param delegate the event listener to delegate event processing to.
055       * @param mask the event mask to use to register this normalizer in the <code>Toolkit</code>.
056       */
057      public void startListening(final Toolkit toolkit, AWTEventListener delegate, long mask) {
058        listener = delegate;
059        weakEventListener = attachAsWeakEventListener(toolkit, this, mask);
060      }
061    
062      /**
063       * Stops listening for events and disposes the delegate event listener.
064       */
065      public void stopListening() {
066        disposeWeakEventListener();
067        listener = null;
068      }
069    
070      private void disposeWeakEventListener() {
071        if (weakEventListener == null) return;
072        weakEventListener.dispose();
073        weakEventListener = null;
074      }
075    
076      /**
077       * Event reception callback.
078       * @param event the dispatached event.
079       */
080      public void eventDispatched(AWTEvent event) {
081        boolean discard = disposedWindowMonitor.isDuplicateDispose(event);
082        if (!discard && listener != null) delegate(event);
083      }
084    
085      private void delegate(AWTEvent e) {
086        listener.eventDispatched(e);
087      }
088    }