/* * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package com.sun.javafx.event; import java.util.HashMap; import java.util.Map; import javafx.event.Event; import javafx.event.EventHandler; import javafx.event.EventType; /** * An {@code EventDispatcher} which allows user event handler / filter * registration and when used in an event dispatch chain it forwards received * events to the appropriate registered handlers / filters. */ public class EventHandlerManager extends BasicEventDispatcher { private final Map, CompositeEventHandler> eventHandlerMap; private final Object eventSource; public EventHandlerManager(final Object eventSource) { this.eventSource = eventSource; eventHandlerMap = new HashMap, CompositeEventHandler>(); } /** * Registers an event handler in {@code EventHandlerManager}. * * @param the specific event class of the handler * @param eventType the type of the events to receive by the handler * @param eventHandler the handler to register * @throws NullPointerException if the event type or handler is null */ public final void addEventHandler( final EventType eventType, final EventHandler eventHandler) { validateEventType(eventType); validateEventHandler(eventHandler); final CompositeEventHandler compositeEventHandler = createGetCompositeEventHandler(eventType); compositeEventHandler.addEventHandler(eventHandler); } /** * Unregisters a previously registered event handler. * * @param the specific event class of the handler * @param eventType the event type from which to unregister * @param eventHandler the handler to unregister * @throws NullPointerException if the event type or handler is null */ public final void removeEventHandler( final EventType eventType, final EventHandler eventHandler) { validateEventType(eventType); validateEventHandler(eventHandler); final CompositeEventHandler compositeEventHandler = (CompositeEventHandler) eventHandlerMap.get(eventType); if (compositeEventHandler != null) { compositeEventHandler.removeEventHandler(eventHandler); } } /** * Registers an event filter in {@code EventHandlerManager}. * * @param the specific event class of the filter * @param eventType the type of the events to receive by the filter * @param eventFilter the filter to register * @throws NullPointerException if the event type or filter is null */ public final void addEventFilter( final EventType eventType, final EventHandler eventFilter) { validateEventType(eventType); validateEventFilter(eventFilter); final CompositeEventHandler compositeEventHandler = createGetCompositeEventHandler(eventType); compositeEventHandler.addEventFilter(eventFilter); } /** * Unregisters a previously registered event filter. * * @param the specific event class of the filter * @param eventType the event type from which to unregister * @param eventFilter the filter to unregister * @throws NullPointerException if the event type or filter is null */ public final void removeEventFilter( final EventType eventType, final EventHandler eventFilter) { validateEventType(eventType); validateEventFilter(eventFilter); final CompositeEventHandler compositeEventHandler = (CompositeEventHandler) eventHandlerMap.get(eventType); if (compositeEventHandler != null) { compositeEventHandler.removeEventFilter(eventFilter); } } /** * Sets the specified singleton handler. There can only be one such handler * specified at a time. * * @param the specific event class of the handler * @param eventType the event type to associate with the given eventHandler * @param eventHandler the handler to register, or null to unregister * @throws NullPointerException if the event type is null */ public final void setEventHandler( final EventType eventType, final EventHandler eventHandler) { validateEventType(eventType); CompositeEventHandler compositeEventHandler = (CompositeEventHandler) eventHandlerMap.get(eventType); if (compositeEventHandler == null) { if (eventHandler == null) { return; } compositeEventHandler = new CompositeEventHandler(); eventHandlerMap.put(eventType, compositeEventHandler); } compositeEventHandler.setEventHandler(eventHandler); } public final EventHandler getEventHandler( final EventType eventType) { final CompositeEventHandler compositeEventHandler = (CompositeEventHandler) eventHandlerMap.get(eventType); return (compositeEventHandler != null) ? compositeEventHandler.getEventHandler() : null; } @Override public final Event dispatchCapturingEvent(Event event) { EventType eventType = event.getEventType(); do { event = dispatchCapturingEvent(eventType, event); eventType = eventType.getSuperType(); } while (eventType != null); return event; } @Override public final Event dispatchBubblingEvent(Event event) { EventType eventType = event.getEventType(); do { event = dispatchBubblingEvent(eventType, event); eventType = eventType.getSuperType(); } while (eventType != null); return event; } private CompositeEventHandler createGetCompositeEventHandler(final EventType eventType) { CompositeEventHandler compositeEventHandler = (CompositeEventHandler) eventHandlerMap.get(eventType); if (compositeEventHandler == null) { compositeEventHandler = new CompositeEventHandler(); eventHandlerMap.put(eventType, compositeEventHandler); } return compositeEventHandler; } protected Object getEventSource() { return eventSource; } private Event dispatchCapturingEvent( final EventType handlerType, Event event) { final CompositeEventHandler compositeEventHandler = eventHandlerMap.get(handlerType); if (compositeEventHandler != null) { // TODO: skip when no filters are registered in the // CompositeEventHandler (RT-23952) event = fixEventSource(event, eventSource); compositeEventHandler.dispatchCapturingEvent(event); } return event; } private Event dispatchBubblingEvent( final EventType handlerType, Event event) { final CompositeEventHandler compositeEventHandler = eventHandlerMap.get(handlerType); if (compositeEventHandler != null) { // TODO: skip when no handlers are registered in the // CompositeEventHandler (RT-23952) event = fixEventSource(event, eventSource); compositeEventHandler.dispatchBubblingEvent(event); } return event; } private static Event fixEventSource(final Event event, final Object eventSource) { return (event.getSource() != eventSource) ? event.copyFor(eventSource, event.getTarget()) : event; } private static void validateEventType(final EventType eventType) { if (eventType == null) { throw new NullPointerException("Event type must not be null"); } } private static void validateEventHandler( final EventHandler eventHandler) { if (eventHandler == null) { throw new NullPointerException("Event handler must not be null"); } } private static void validateEventFilter( final EventHandler eventFilter) { if (eventFilter == null) { throw new NullPointerException("Event filter must not be null"); } } }