001 /* 002 * Created on Nov 21, 2008 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 005 * in compliance with 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 010 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 011 * or implied. See the License for the specific language governing permissions and limitations under 012 * the License. 013 * 014 * Copyright @2008-2010 the original author or authors. 015 */ 016 package org.fest.swing.driver; 017 018 import static org.fest.swing.query.ComponentVisibleQuery.isVisible; 019 import static org.fest.swing.timing.Pause.pause; 020 import static org.fest.swing.util.TimeoutWatch.startWatchWithTimeoutOf; 021 022 import java.awt.Component; 023 import java.awt.event.ComponentAdapter; 024 import java.awt.event.ComponentEvent; 025 026 import org.fest.swing.annotation.RunsInEDT; 027 import org.fest.swing.exception.WaitTimedOutError; 028 import org.fest.swing.util.TimeoutWatch; 029 030 /** 031 * Understands waiting for a <code>{@link Component}</code> to be shown. 032 * 033 * @author Alex Ruiz 034 */ 035 public final class ComponentShownWaiter extends ComponentAdapter { 036 037 private static final int DEFAULT_TIMEOUT = 5000; 038 private static final int DEFAULT_SLEEP_TIME = 10; 039 040 private Component toWaitFor; 041 private volatile boolean shown; 042 043 /** 044 * Waits until the given component is shown on the screen, using a timeout of 5 seconds. 045 * @param toWaitFor the component to wait for. 046 * @throws WaitTimedOutError if the component is not shown before the default timeout of 5 seconds. 047 */ 048 public static void waitTillShown(Component toWaitFor) { 049 new ComponentShownWaiter(toWaitFor).startWaiting(DEFAULT_TIMEOUT); 050 } 051 052 /** 053 * Waits until the given component is shown on the screen. 054 * @param toWaitFor the component to wait for. 055 * @param timeout the amount to time (in milliseconds) to wait for the component to be shown. 056 * @throws WaitTimedOutError if the component is not shown before the given timeout expires. 057 */ 058 public static void waitTillShown(Component toWaitFor, long timeout) { 059 new ComponentShownWaiter(toWaitFor).startWaiting(timeout); 060 } 061 062 private ComponentShownWaiter(Component toWaitFor) { 063 this.toWaitFor = toWaitFor; 064 toWaitFor.addComponentListener(this); 065 } 066 067 private void startWaiting(long timeout) { 068 if (alreadyVisible()) return; 069 TimeoutWatch watch = startWatchWithTimeoutOf(timeout); 070 while (!shown) { 071 pause(DEFAULT_SLEEP_TIME); 072 if (watch.isTimeOut()) { 073 done(); 074 throw new WaitTimedOutError("Timed out waiting for component to be visible"); 075 } 076 } 077 } 078 079 private boolean alreadyVisible() { 080 if (!isVisible(toWaitFor)) return false; 081 done(); 082 return true; 083 } 084 085 /** 086 * Notification that the component to wait for is finally shown on the screen. 087 * @param e the event raised when the component has been made visible. 088 */ 089 @RunsInEDT 090 @Override public void componentShown(ComponentEvent e) { 091 shown = true; 092 done(); 093 } 094 095 private void done() { 096 toWaitFor.removeComponentListener(this); 097 toWaitFor = null; 098 } 099 }