### Question:
ExpiringSwingTimer extends GhidraSwingTimer { public static ExpiringSwingTimer runWhen(BooleanSupplier isReady, int expireMs, Runnable runnable) { int delay = 250; ExpiringSwingTimer timer = new ExpiringSwingTimer(delay, expireMs, isReady, runnable); timer.start(); return timer; } ExpiringSwingTimer(int delay, int expireMs, BooleanSupplier isReady,
			Runnable runnable); static ExpiringSwingTimer runWhen(BooleanSupplier isReady,
			int expireMs,
			Runnable runnable); boolean didRun(); @Override void start(); boolean isExpired(); @Override void setTimerCallback(TimerCallback callback);  }### Answer:
@Test public void testRunWhenReady() { int waitCount = 2; AtomicInteger counter = new AtomicInteger(); BooleanSupplier isReady = () -> { return counter.incrementAndGet() > waitCount; }; AtomicInteger runCount = new AtomicInteger(); Runnable r = () -> { runCount.incrementAndGet(); }; ExpiringSwingTimer.runWhen(isReady, 10000, r); waitFor(() -> runCount.get() > 0); assertTrue("Timer did not wait for the condition to be true", counter.get() > waitCount); assertEquals("Client code was run more than once", 1, runCount.get()); }
@Test public void testRunWhenReady_Timeout() { BooleanSupplier isReady = () -> { return false; }; AtomicBoolean didRun = new AtomicBoolean(); Runnable r = () -> didRun.set(true); ExpiringSwingTimer timer = ExpiringSwingTimer.runWhen(isReady, 500, r); waitFor(() -> !timer.isRunning()); assertFalse(didRun.get()); }