/******************************************************************************* * Copyright (c) 2014 BREDEX GmbH. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * BREDEX GmbH - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.jubula.rc.javafx.listener.sync; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; import org.eclipse.jubula.rc.javafx.driver.EventThreadQueuerJavaFXImpl; import org.eclipse.jubula.rc.javafx.utils.JBExecutors; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.stage.Stage; import javafx.stage.Window; /** * "Synchronizes" by waiting a set amount of time. Even if the Stage resizes * before the timeout has elapsed, the full time is waited. After waiting the * set amount of time, the lock is released (whether the Stage has been * appropriately resized or not). */ class StageResizeTimeoutSync implements IStageResizeSync { /** * Acquires the lock */ private class Locker implements ChangeListener<Boolean> { /** * Releases the lock */ private Unlocker m_unlocker = new Unlocker(); @Override public void changed( ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { lock(); } /** * Acquires the lock and defines the criteria necessary to release the * lock. This method may only be called on the FX Thread. */ public void lock() { EventThreadQueuerJavaFXImpl.checkEventThread(); m_lock.lock(); m_executor.schedule( m_unlocker, 2000, TimeUnit.MILLISECONDS); } } /** * Releases the lock. This can be used as a fallback if the condition for * releasing the lock is not fulfilled within a specified amount of time. */ private class Unlocker implements Runnable { @Override public void run() { Platform.runLater(new Runnable() { @Override public void run() { m_lock.unlock(); } }); } } /** The lock used for synchronization. */ private final ReentrantLock m_lock = new ReentrantLock(); /** the executor for fallback unlocking */ private final ScheduledExecutorService m_executor = JBExecutors.newSingleDaemonThreadScheduledExecutor( StageResizeTimeoutSync.class.getSimpleName()); /** * Acquires the lock */ private Locker m_locker = new Locker(); @Override public void register(Window win) { if (win instanceof Stage) { ((Stage) win).maximizedProperty().addListener(m_locker); m_locker.lock(); } } @Override public void deregister(Window win) { if (win instanceof Stage) { ((Stage) win).maximizedProperty().removeListener(m_locker); } } @Override public void await() { EventThreadQueuerJavaFXImpl.checkNotEventThread(); EventThreadQueuerJavaFXImpl.waitForIdle(); m_lock.lock(); m_lock.unlock(); } }