1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski import java.awt.event.ActionListener; 25*b1cdbd2cSJim Jagielski import javax.swing.*; 26*b1cdbd2cSJim Jagielski import java.awt.*; 27*b1cdbd2cSJim Jagielski import java.util.*; 28*b1cdbd2cSJim Jagielski 29*b1cdbd2cSJim Jagielski import com.sun.star.awt.XTopWindowListener; 30*b1cdbd2cSJim Jagielski import com.sun.star.uno.UnoRuntime; 31*b1cdbd2cSJim Jagielski import com.sun.star.bridge.XUnoUrlResolver; 32*b1cdbd2cSJim Jagielski import com.sun.star.lang.XMultiServiceFactory; 33*b1cdbd2cSJim Jagielski import com.sun.star.accessibility.*; 34*b1cdbd2cSJim Jagielski import com.sun.star.awt.XExtendedToolkit; 35*b1cdbd2cSJim Jagielski 36*b1cdbd2cSJim Jagielski /** This class is used as a thread and registers or unregsiters a listener 37*b1cdbd2cSJim Jagielski given the constructor at all nodes of a tree of accessibility objects. 38*b1cdbd2cSJim Jagielski */ 39*b1cdbd2cSJim Jagielski public class RegistrationThread 40*b1cdbd2cSJim Jagielski implements Runnable 41*b1cdbd2cSJim Jagielski { 42*b1cdbd2cSJim Jagielski /** Start a new thread that adds or removes the given listener at all 43*b1cdbd2cSJim Jagielski accessible objects in the sub-tree rooted in the given accessible 44*b1cdbd2cSJim Jagielski object. 45*b1cdbd2cSJim Jagielski @param aListener 46*b1cdbd2cSJim Jagielski The listener that is added or removed. 47*b1cdbd2cSJim Jagielski @param xRoot 48*b1cdbd2cSJim Jagielski The root of the sub-tree of accessibility objects. 49*b1cdbd2cSJim Jagielski @param bRegister 50*b1cdbd2cSJim Jagielski This flag decides whether to add or remove the listener. 51*b1cdbd2cSJim Jagielski */ RegistrationThread( EventListenerProxy aListener, XAccessibleContext xRoot, boolean bRegister, boolean bShowMessages)52*b1cdbd2cSJim Jagielski public RegistrationThread ( 53*b1cdbd2cSJim Jagielski EventListenerProxy aListener, 54*b1cdbd2cSJim Jagielski XAccessibleContext xRoot, 55*b1cdbd2cSJim Jagielski boolean bRegister, 56*b1cdbd2cSJim Jagielski boolean bShowMessages) 57*b1cdbd2cSJim Jagielski { 58*b1cdbd2cSJim Jagielski maListener = aListener; 59*b1cdbd2cSJim Jagielski mxRoot = xRoot; 60*b1cdbd2cSJim Jagielski mbRegister = bRegister; 61*b1cdbd2cSJim Jagielski mbShowMessages = bShowMessages; 62*b1cdbd2cSJim Jagielski 63*b1cdbd2cSJim Jagielski if (mxRoot != null) 64*b1cdbd2cSJim Jagielski { 65*b1cdbd2cSJim Jagielski if (mbShowMessages) 66*b1cdbd2cSJim Jagielski MessageArea.println ("starting to register at " + mxRoot.getAccessibleName()); 67*b1cdbd2cSJim Jagielski new Thread (this, "RegistrationThread").start(); 68*b1cdbd2cSJim Jagielski } 69*b1cdbd2cSJim Jagielski } 70*b1cdbd2cSJim Jagielski 71*b1cdbd2cSJim Jagielski 72*b1cdbd2cSJim Jagielski run()73*b1cdbd2cSJim Jagielski public void run () 74*b1cdbd2cSJim Jagielski { 75*b1cdbd2cSJim Jagielski System.out.println ("starting registration"); 76*b1cdbd2cSJim Jagielski long nNodeCount = traverseTree (mxRoot); 77*b1cdbd2cSJim Jagielski System.out.println ("ending registration"); 78*b1cdbd2cSJim Jagielski if (mbShowMessages) 79*b1cdbd2cSJim Jagielski { 80*b1cdbd2cSJim Jagielski if ( ! mbRegister) 81*b1cdbd2cSJim Jagielski MessageArea.print ("un"); 82*b1cdbd2cSJim Jagielski MessageArea.println ("registered at " + nNodeCount 83*b1cdbd2cSJim Jagielski + " objects in accessibility tree of " + mxRoot.getAccessibleName()); 84*b1cdbd2cSJim Jagielski } 85*b1cdbd2cSJim Jagielski } 86*b1cdbd2cSJim Jagielski 87*b1cdbd2cSJim Jagielski 88*b1cdbd2cSJim Jagielski 89*b1cdbd2cSJim Jagielski 90*b1cdbd2cSJim Jagielski /** Register this object as listener for accessibility events at all nodes 91*b1cdbd2cSJim Jagielski of the given tree. 92*b1cdbd2cSJim Jagielski @param xRoot 93*b1cdbd2cSJim Jagielski The root node of the tree at which to register. 94*b1cdbd2cSJim Jagielski */ traverseTree(XAccessibleContext xRoot)95*b1cdbd2cSJim Jagielski public long traverseTree (XAccessibleContext xRoot) 96*b1cdbd2cSJim Jagielski { 97*b1cdbd2cSJim Jagielski long nNodeCount = 0; 98*b1cdbd2cSJim Jagielski if (xRoot != null) 99*b1cdbd2cSJim Jagielski { 100*b1cdbd2cSJim Jagielski // Register the root node. 101*b1cdbd2cSJim Jagielski XAccessibleEventBroadcaster xBroadcaster = 102*b1cdbd2cSJim Jagielski (XAccessibleEventBroadcaster) UnoRuntime.queryInterface ( 103*b1cdbd2cSJim Jagielski XAccessibleEventBroadcaster.class, 104*b1cdbd2cSJim Jagielski xRoot); 105*b1cdbd2cSJim Jagielski if (xBroadcaster != null) 106*b1cdbd2cSJim Jagielski { 107*b1cdbd2cSJim Jagielski if (mbRegister) 108*b1cdbd2cSJim Jagielski xBroadcaster.addEventListener (maListener); 109*b1cdbd2cSJim Jagielski else 110*b1cdbd2cSJim Jagielski xBroadcaster.removeEventListener (maListener); 111*b1cdbd2cSJim Jagielski nNodeCount += 1; 112*b1cdbd2cSJim Jagielski } 113*b1cdbd2cSJim Jagielski 114*b1cdbd2cSJim Jagielski // Call this method recursively to register all sub-trees. 115*b1cdbd2cSJim Jagielski try 116*b1cdbd2cSJim Jagielski { 117*b1cdbd2cSJim Jagielski int nChildCount = xRoot.getAccessibleChildCount(); 118*b1cdbd2cSJim Jagielski for (int i=0; i<nChildCount; i++) 119*b1cdbd2cSJim Jagielski { 120*b1cdbd2cSJim Jagielski XAccessible xChild = xRoot.getAccessibleChild (i); 121*b1cdbd2cSJim Jagielski if (xChild != null) 122*b1cdbd2cSJim Jagielski nNodeCount += traverseTree (xChild.getAccessibleContext()); 123*b1cdbd2cSJim Jagielski } 124*b1cdbd2cSJim Jagielski } 125*b1cdbd2cSJim Jagielski catch (com.sun.star.lang.IndexOutOfBoundsException aException) 126*b1cdbd2cSJim Jagielski { 127*b1cdbd2cSJim Jagielski // The set of children has changed since our last call to 128*b1cdbd2cSJim Jagielski // getAccesibleChildCount(). Don't try any further on this 129*b1cdbd2cSJim Jagielski // sub-tree. 130*b1cdbd2cSJim Jagielski } 131*b1cdbd2cSJim Jagielski catch (com.sun.star.lang.DisposedException aException) 132*b1cdbd2cSJim Jagielski { 133*b1cdbd2cSJim Jagielski // The child has been destroyed since our last call to 134*b1cdbd2cSJim Jagielski // getAccesibleChildCount(). That is OK. Don't try any 135*b1cdbd2cSJim Jagielski // further on this sub-tree. 136*b1cdbd2cSJim Jagielski } 137*b1cdbd2cSJim Jagielski } 138*b1cdbd2cSJim Jagielski return nNodeCount; 139*b1cdbd2cSJim Jagielski } 140*b1cdbd2cSJim Jagielski 141*b1cdbd2cSJim Jagielski private EventListenerProxy maListener; 142*b1cdbd2cSJim Jagielski private XAccessibleContext mxRoot; 143*b1cdbd2cSJim Jagielski private boolean mbRegister; 144*b1cdbd2cSJim Jagielski private boolean mbShowMessages; 145*b1cdbd2cSJim Jagielski } 146