/******************************************************************************* * Copyright (c) 2013 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; import org.eclipse.jubula.rc.javafx.utils.JBExecutors; import javafx.application.Platform; import javafx.concurrent.Service; import javafx.concurrent.Task; import javafx.concurrent.WorkerStateEvent; import javafx.event.EventHandler; import javafx.scene.input.MouseEvent; /** * Alters the JavaFx mouse moved event, which is always fired when the mouse * moves on a node, to an event that is only fired when a mouse move is over. * * @author BREDEX GmbH * @created 18.10.2013 */ public class MouseMoveDone implements EventHandler<MouseEvent> { /** deadzone on the x-axis **/ private double m_deltaX; /** deadzone on the y-axis **/ private double m_deltaY; /** * threshold the threshold in milliseconds when a mouse move is interpreted * as done **/ private final long m_threshold; /** Last event **/ private volatile MouseEvent m_lastEvent; /** Timer Service **/ private Service<MouseEvent> m_timeService; /** * * @param threshold * threshold the threshold in milliseconds when a mouse move is * interpreted as done * @param deltaX * deadzone on the x-axis * @param deltaY * deadzone on the y-axis */ public MouseMoveDone(long threshold, double deltaX, double deltaY) { m_threshold = threshold; m_deltaX = deltaX; m_deltaY = deltaY; m_timeService = new Service<MouseEvent>() { @Override protected Task<MouseEvent> createTask() { return new WaitingTask(); } }; m_timeService.setExecutor( JBExecutors.newSingleDaemonThreadExecutor( MouseMoveDone.class.getSimpleName())); } @Override public void handle(MouseEvent event) { if (m_lastEvent == null) { m_lastEvent = event; } double currDX = Math.abs((event.getSceneX() - m_lastEvent.getSceneX())); double currDY = Math.abs((event.getSceneX() - m_lastEvent.getSceneX())); if (currDX >= m_deltaX && currDY >= m_deltaY) { m_timeService.restart(); m_lastEvent = event; } } /** * Adds a handler to the Service. This handler will be notified when the * Task in this service succeeds. Therefore when a mouse move is completed. * * @param hl * the handler */ public void addMoveDoneHandler(final EventHandler<WorkerStateEvent> hl) { Platform.runLater(new Runnable() { @Override public void run() { m_timeService.setOnSucceeded(hl); } }); } /** * Removes a handler from the Service. * * @param hl * the handler */ public void removeMoveDoneHandler(final EventHandler<WorkerStateEvent> hl) { Platform.runLater(new Runnable() { @Override public void run() { m_timeService.removeEventHandler( WorkerStateEvent.WORKER_STATE_SUCCEEDED, hl); } }); } /** * Realizes the waiting * */ private class WaitingTask extends Task<MouseEvent> { @Override protected MouseEvent call() throws Exception { Thread.sleep(m_threshold); return m_lastEvent; } } }