diff options
Diffstat (limited to 'odk/examples/DevelopersGuide/Accessibility/EventListenerProxy.java')
-rw-r--r-- | odk/examples/DevelopersGuide/Accessibility/EventListenerProxy.java | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/odk/examples/DevelopersGuide/Accessibility/EventListenerProxy.java b/odk/examples/DevelopersGuide/Accessibility/EventListenerProxy.java new file mode 100644 index 000000000000..273f6146a6cc --- /dev/null +++ b/odk/examples/DevelopersGuide/Accessibility/EventListenerProxy.java @@ -0,0 +1,232 @@ +/************************************************************************* + * + * The Contents of this file are made available subject to the terms of + * the BSD license. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Sun Microsystems, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + *************************************************************************/ + +import com.sun.star.accessibility.XAccessible; +import com.sun.star.accessibility.XAccessibleEventListener; +import com.sun.star.accessibility.AccessibleEventObject; +import com.sun.star.lang.EventObject; +import com.sun.star.awt.XTopWindowListener; +import com.sun.star.uno.UnoRuntime; + +import java.util.LinkedList; + +/** This class acts as a proxy for the simple screen reader. It waits for + two types of events: + 1. Accessibility events signal modifications concerning accessibility + objects. + 2. Top window events inform the listener about new or removed windows. + + This class exists because events had to be handled in a seperate thread + to avoid dead locks: The thread that receives an event must no call back + to the Office directly. + + Soon this should not be necessary anymore. There is now a flag which + switches between synchronous and asynchronous callbacks. + + All reveived events are eventually forwarded to the actual listener. In + this way it decouples the Office from the listener. +*/ +class EventListenerProxy + implements Runnable, XAccessibleEventListener, XTopWindowListener +{ + public EventListenerProxy (EventHandler aListener) + { + maListener = aListener; + mbAsynchron = true; + if (mbAsynchron) + { + maEventQueue = new LinkedList(); + new Thread (this, "EventListenerProxy").start(); + } + } + + private void addEvent (Runnable aEventObject) + { + if (mbAsynchron) + synchronized (maEventQueue) + { + maEventQueue.addLast (aEventObject); + // Tell the queue that there is a new event in the queue. + maEventQueue.notify(); + } + else + { + System.out.println ("running " + aEventObject); + aEventObject.run(); + System.out.println (" done"); + } + } + + + + + /** In an infinite loop, check for events to deliver, then wait on lock + (which will be notified when new events arrive) + */ + public void run () + { + while (true) + { + // Process all events that are currently in the queue. + Runnable aEvent; + do + { + synchronized (maEventQueue) + { + if (maEventQueue.size() > 0) + aEvent = (Runnable)maEventQueue.removeFirst(); + else + aEvent = null; + } + + if (aEvent != null) + { + try + { + aEvent.run(); + } + catch (Throwable aException) + { + MessageArea.println( + "Exception during event delivery: " + aException); + aException.printStackTrace(); + } + } + } + while (aEvent != null); + + // Now that the queue is empty go to sleep again. + try + { + synchronized (maEventQueue) + { + maEventQueue.wait(); + } + } + catch (Exception aException) + { + // Ignore this exception since there is not much + // that we can do about it. + } + } + } + + + public void disposing( final EventObject aEvent) + { + addEvent (new Runnable() + { + public void run() + { + maListener.disposing (aEvent); + } + } ); + } + + public void notifyEvent (final AccessibleEventObject aEvent) + { + addEvent ( + new Runnable() + { + public void run() + { + maListener.notifyEvent (aEvent); + } + } ); + } + + public void windowOpened (final com.sun.star.lang.EventObject aEvent) + { + addEvent ( + new Runnable() + { + public void run() + { + maListener.windowOpened ( + (XAccessible) UnoRuntime.queryInterface( + XAccessible.class, + aEvent.Source)); + } + } ); + } + public void windowClosing (final com.sun.star.lang.EventObject aEvent) + { + // Ignored. + } + public void windowClosed (final com.sun.star.lang.EventObject aEvent) + { + addEvent ( + new Runnable() + { + public void run() + { + maListener.windowClosed ( + (XAccessible) UnoRuntime.queryInterface( + XAccessible.class, + aEvent.Source)); + } + } ); + } + public void windowMinimized (com.sun.star.lang.EventObject aEvent) + { + // Ignored. + } + public void windowNormalized (com.sun.star.lang.EventObject aEvent) + { + // Ignored. + } + public void windowActivated (com.sun.star.lang.EventObject aEvent) + { + // Ignored. + } + public void windowDeactivated (com.sun.star.lang.EventObject aEvent) + { + // Ignored. + } + + /** The queue of event objects, LinkedList<Runnable>. + The queue object will also serve as lock for the consumer/producer type + syncronization. + */ + private LinkedList maEventQueue; + + /** This is the actual listener that the events will eventually forwarded to. + */ + private EventHandler maListener; + + /** This flag determines whether event forwarding is done asynchroniously + or synchroniously. + */ + private boolean mbAsynchron; +} |