001    /*
002     * Created on Oct 31, 2007
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 @2007-2010 the original author or authors.
014     */
015    package org.fest.swing.hierarchy;
016    
017    import static javax.swing.SwingUtilities.invokeLater;
018    import static org.fest.swing.util.AWTEvents.*;
019    
020    import java.awt.AWTEvent;
021    import java.awt.Window;
022    import java.awt.event.AWTEventListener;
023    
024    import org.fest.swing.annotation.RunsInEDT;
025    
026    /**
027     * Understands automatic filtering of auto-generated Swing dialogs.
028     *
029     * @author Alex Ruiz
030     */
031    public final class TransientWindowListener implements AWTEventListener {
032    
033      private final WindowFilter filter;
034    
035      TransientWindowListener(WindowFilter filter) {
036        this.filter = filter;
037      }
038    
039      /** {@inheritDoc} */
040      @RunsInEDT
041      public void eventDispatched(AWTEvent e) {
042        if (windowOpened(e) || windowShown(e)) {
043          filter(sourceOf(e));
044          return;
045        }
046        if (windowClosed(e)) {
047          final Window w = sourceOf(e);
048          // *Any* window disposal should result in the window being ignored, at least until it is again displayed.
049          if (filter.isIgnored(w)) return;
050          filter.implicitlyIgnore(w);
051          // Filter this window only *after* any handlers for this event have finished.
052          invokeLater(new IgnoreWindowTask(w, filter));
053        }
054      }
055    
056      private Window sourceOf(AWTEvent e) {
057        return (Window) e.getSource();
058      }
059    
060      private void filter(Window w) {
061        if (filter.isImplicitlyIgnored(w)) {
062          filter.recognize(w);
063          return;
064        }
065        // Catch new sub-windows of filtered windows (i.e. dialogs generated by a test harness UI).
066        filterIfParentIsFiltered(w);
067      }
068    
069      private void filterIfParentIsFiltered(Window w) {
070        if (!filter.isIgnored(w.getParent())) return;
071        filter.ignore(w);
072      }
073    }