/* * Bibliothek - DockingFrames * Library built on Java/Swing, allows the user to "drag and drop" * panels containing any Swing-Component the developer likes to add. * * Copyright (C) 2011 Benjamin Sigg * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Benjamin Sigg * benjamin_sigg@gmx.ch * CH - Switzerland */ package bibliothek.gui.dock.control; import java.awt.AWTEvent; import java.awt.Toolkit; import java.awt.event.AWTEventListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.util.ArrayList; import java.util.List; import bibliothek.gui.DockController; import bibliothek.gui.dock.event.ControllerSetupListener; import bibliothek.gui.dock.util.PropertyValue; /** * This default implementation of a {@link GlobalMouseDispatcher} uses an {@link AWTEventListener} is possible, or * just forwards events that are delivered to the {@link #dispatch(MouseEvent)} method. * @author Benjamin Sigg */ public class DefaultGlobalMouseDispatcher implements GlobalMouseDispatcher { /** The listener to all AWT events*/ private AWTEventListener listener; private List<MouseListener> mouseListeners = new ArrayList<MouseListener>(); private MouseListener[] mouseListenersCache = null; private List<MouseMotionListener> mouseMotionListeners = new ArrayList<MouseMotionListener>(); private MouseMotionListener[] mouseMotionListenersCache = null; private List<MouseWheelListener> mouseWheelListeners = new ArrayList<MouseWheelListener>(); private MouseWheelListener[] mouseWheelListenersCache = null; /** whether the application is in restricted mode or not */ private PropertyValue<Boolean> restricted = new PropertyValue<Boolean>( DockController.RESTRICTED_ENVIRONMENT ){ protected void valueChanged( Boolean oldValue, Boolean newValue ){ updateRestricted(); } }; /** * Creates a new dispatcher. * @param controller the controller in whose realm this dispatcher works * @param setup tells when the setup phase of <code>controller</code> is finished */ public DefaultGlobalMouseDispatcher( DockController controller, ControllerSetupCollection setup ){ setup.add( new ControllerSetupListener(){ public void done( DockController controller ){ restricted.setProperties( controller ); updateRestricted(); } } ); } public void dispatch( MouseEvent event ){ switch( event.getID() ){ case MouseEvent.MOUSE_CLICKED: for( MouseListener listener : getMouseListeners() ){ listener.mouseClicked( event ); } break; case MouseEvent.MOUSE_DRAGGED: for( MouseMotionListener listener : getMouseMotionListeners() ){ listener.mouseDragged( event ); } break; case MouseEvent.MOUSE_ENTERED: for( MouseListener listener : getMouseListeners() ){ listener.mouseEntered( event ); } break; case MouseEvent.MOUSE_EXITED: for( MouseListener listener : getMouseListeners() ){ listener.mouseExited( event ); } break; case MouseEvent.MOUSE_MOVED: for( MouseMotionListener listener : getMouseMotionListeners() ){ listener.mouseMoved( event ); } break; case MouseEvent.MOUSE_PRESSED: for( MouseListener listener : getMouseListeners() ){ listener.mousePressed( event ); } break; case MouseEvent.MOUSE_RELEASED: for( MouseListener listener : getMouseListeners() ){ listener.mouseReleased( event ); } break; case MouseEvent.MOUSE_WHEEL: for( MouseWheelListener listener : getMouseWheelListeners() ){ listener.mouseWheelMoved( (MouseWheelEvent)event ); } break; default: throw new IllegalStateException( "unknown type of MouseEvent: " + event ); } } public synchronized void addMouseListener( MouseListener listener ){ mouseListeners.add( listener ); mouseListenersCache = null; } public synchronized void removeMouseListener( MouseListener listener ){ mouseListeners.remove( listener ); mouseListenersCache = null; } /** * Gets all the {@link MouseListener}s that are currently registered. * @return all the listeners */ protected synchronized MouseListener[] getMouseListeners(){ if( mouseListenersCache == null ) { mouseListenersCache = mouseListeners.toArray( new MouseListener[mouseListeners.size()] ); } return mouseListenersCache; } public synchronized void addMouseMotionListener( MouseMotionListener listener ){ mouseMotionListeners.add( listener ); mouseMotionListenersCache = null; } public synchronized void removeMouseMotionListener( MouseMotionListener listener ){ mouseMotionListeners.remove( listener ); mouseMotionListenersCache = null; } /** * Gets all the {@link MouseMotionListener}s that are currently registered. * @return all the listeners */ protected synchronized MouseMotionListener[] getMouseMotionListeners(){ if( mouseMotionListenersCache == null ) { mouseMotionListenersCache = mouseMotionListeners.toArray( new MouseMotionListener[mouseMotionListeners.size()] ); } return mouseMotionListenersCache; } public synchronized void addMouseWheelListener( MouseWheelListener listener ){ mouseWheelListeners.add( listener ); mouseWheelListenersCache = null; } public synchronized void removeMouseWheelListener( MouseWheelListener listener ){ mouseWheelListeners.remove( listener ); mouseWheelListenersCache = null; } /** * Gets all the {@link MouseWheelListener}s that are currently registered. * @return all the listeners */ protected synchronized MouseWheelListener[] getMouseWheelListeners(){ if( mouseWheelListenersCache == null ) { mouseWheelListenersCache = mouseWheelListeners.toArray( new MouseWheelListener[mouseWheelListeners.size()] ); } return mouseWheelListenersCache; } private void updateRestricted(){ if( restricted.getProperties() != null ) { if( !restricted.getValue() ) { if( listener == null ) { listener = createListener(); try { Toolkit.getDefaultToolkit().addAWTEventListener( listener, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_WHEEL_EVENT_MASK ); } catch( SecurityException ex ) { System.err.println( "Can't register AWTEventListener, support for global MouseEvents disabled" ); ex.printStackTrace(); } } } else { if( listener != null ) { Toolkit.getDefaultToolkit().removeAWTEventListener( listener ); listener = null; } } } } public void kill(){ if( listener != null ) { Toolkit.getDefaultToolkit().removeAWTEventListener( listener ); listener = null; } restricted.setProperties( (DockController) null ); } /** * Creates a listener which will receive mouse-events. * @return the listener */ protected AWTEventListener createListener(){ return new AWTEventListener(){ public void eventDispatched( AWTEvent event ){ if( event instanceof MouseEvent ) { dispatch( (MouseEvent) event ); } } }; } }