1*1b0aaa91SAndrew Rist /************************************************************** 2*1b0aaa91SAndrew Rist * 3*1b0aaa91SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*1b0aaa91SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*1b0aaa91SAndrew Rist * distributed with this work for additional information 6*1b0aaa91SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*1b0aaa91SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*1b0aaa91SAndrew Rist * "License"); you may not use this file except in compliance 9*1b0aaa91SAndrew Rist * with the License. You may obtain a copy of the License at 10*1b0aaa91SAndrew Rist * 11*1b0aaa91SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*1b0aaa91SAndrew Rist * 13*1b0aaa91SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*1b0aaa91SAndrew Rist * software distributed under the License is distributed on an 15*1b0aaa91SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*1b0aaa91SAndrew Rist * KIND, either express or implied. See the License for the 17*1b0aaa91SAndrew Rist * specific language governing permissions and limitations 18*1b0aaa91SAndrew Rist * under the License. 19*1b0aaa91SAndrew Rist * 20*1b0aaa91SAndrew Rist *************************************************************/ 21*1b0aaa91SAndrew Rist 22cdf0e10cSrcweir import javax.swing.event.TreeModelEvent; 23cdf0e10cSrcweir import javax.swing.event.TreeModelListener; 24cdf0e10cSrcweir import javax.swing.tree.TreePath; 25cdf0e10cSrcweir 26cdf0e10cSrcweir 27cdf0e10cSrcweir import java.util.Vector; 28cdf0e10cSrcweir import java.util.HashMap; 29cdf0e10cSrcweir import java.util.Enumeration; 30cdf0e10cSrcweir 31cdf0e10cSrcweir import com.sun.star.accessibility.*; 32cdf0e10cSrcweir 33cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime; 34cdf0e10cSrcweir import com.sun.star.uno.XInterface; 35cdf0e10cSrcweir import com.sun.star.uno.Any; 36cdf0e10cSrcweir import com.sun.star.lang.EventObject; 37cdf0e10cSrcweir import com.sun.star.lang.XServiceInfo; 38cdf0e10cSrcweir import com.sun.star.lang.XServiceName; 39cdf0e10cSrcweir 40cdf0e10cSrcweir public class AccessibilityTreeModel 41cdf0e10cSrcweir extends AccessibilityTreeModelBase 42cdf0e10cSrcweir { 43cdf0e10cSrcweir public boolean mbVerbose = false; 44cdf0e10cSrcweir AccessibilityTreeModel(AccessibleTreeNode aRoot)45cdf0e10cSrcweir public AccessibilityTreeModel (AccessibleTreeNode aRoot) 46cdf0e10cSrcweir { 47cdf0e10cSrcweir // create default node (unless we have a 'proper' node) 48cdf0e10cSrcweir if( ! (aRoot instanceof AccessibleTreeNode) ) 49cdf0e10cSrcweir aRoot = new StringNode ("Root", null); 50cdf0e10cSrcweir setRoot (aRoot); 51cdf0e10cSrcweir 52cdf0e10cSrcweir maNodeMap = new NodeMap(); 53cdf0e10cSrcweir 54cdf0e10cSrcweir maEventListener = new EventListener (this); 55cdf0e10cSrcweir mxListener = new QueuedListener (maEventListener); 56cdf0e10cSrcweir } 57cdf0e10cSrcweir clear()58cdf0e10cSrcweir public void clear () 59cdf0e10cSrcweir { 60cdf0e10cSrcweir maNodeMap.Clear(); 61cdf0e10cSrcweir } 62cdf0e10cSrcweir 63cdf0e10cSrcweir /** Lock the tree. While the tree is locked, events from the outside are 64cdf0e10cSrcweir not processed. Lock the tree when you change its internal structure. 65cdf0e10cSrcweir */ lock()66cdf0e10cSrcweir public void lock () 67cdf0e10cSrcweir { 68cdf0e10cSrcweir mnLockCount += 1; 69cdf0e10cSrcweir } 70cdf0e10cSrcweir 71cdf0e10cSrcweir /** Unlock the tree. After unlocking the tree as many times as locking 72cdf0e10cSrcweir it, a treeStructureChange event is sent to the event listeners. 73cdf0e10cSrcweir @param aNodeHint 74cdf0e10cSrcweir If not null and treeStructureChange events are thrown then this 75cdf0e10cSrcweir node is used as root of the modified subtree. 76cdf0e10cSrcweir */ unlock(AccessibleTreeNode aNodeHint)77cdf0e10cSrcweir public void unlock (AccessibleTreeNode aNodeHint) 78cdf0e10cSrcweir { 79cdf0e10cSrcweir mnLockCount -= 1; 80cdf0e10cSrcweir if (mnLockCount == 0) 81cdf0e10cSrcweir fireTreeStructureChanged ( 82cdf0e10cSrcweir new TreeModelEvent (this, 83cdf0e10cSrcweir new TreePath (aNodeHint.createPath()))); 84cdf0e10cSrcweir } 85cdf0e10cSrcweir 86cdf0e10cSrcweir 87cdf0e10cSrcweir 88cdf0e10cSrcweir 89cdf0e10cSrcweir /** Inform all listeners (especially the renderer) of a change of the 90cdf0e10cSrcweir tree's structure. 91cdf0e10cSrcweir @param aNode This node specifies the sub tree in which all changes 92cdf0e10cSrcweir take place. 93cdf0e10cSrcweir */ FireTreeStructureChanged(AccessibleTreeNode aNode)94cdf0e10cSrcweir public void FireTreeStructureChanged (AccessibleTreeNode aNode) 95cdf0e10cSrcweir { 96cdf0e10cSrcweir } 97cdf0e10cSrcweir 98cdf0e10cSrcweir 99cdf0e10cSrcweir 100cdf0e10cSrcweir 101cdf0e10cSrcweir setRoot(AccessibleTreeNode aRoot)102cdf0e10cSrcweir public synchronized void setRoot (AccessibleTreeNode aRoot) 103cdf0e10cSrcweir { 104cdf0e10cSrcweir if (getRoot() == null) 105cdf0e10cSrcweir super.setRoot (aRoot); 106cdf0e10cSrcweir else 107cdf0e10cSrcweir { 108cdf0e10cSrcweir lock (); 109cdf0e10cSrcweir maNodeMap.ForEach (new NodeMapCallback () { 110cdf0e10cSrcweir public void Apply (AccTreeNode aNode) 111cdf0e10cSrcweir { 112cdf0e10cSrcweir if (maCanvas != null) 113cdf0e10cSrcweir maCanvas.removeNode (aNode); 114cdf0e10cSrcweir removeAccListener ((AccTreeNode)aNode); 115cdf0e10cSrcweir } 116cdf0e10cSrcweir }); 117cdf0e10cSrcweir maNodeMap.Clear (); 118cdf0e10cSrcweir 119cdf0e10cSrcweir setRoot (aRoot); 120cdf0e10cSrcweir unlock (aRoot); 121cdf0e10cSrcweir } 122cdf0e10cSrcweir } 123cdf0e10cSrcweir 124cdf0e10cSrcweir 125cdf0e10cSrcweir // 126cdf0e10cSrcweir // child management: 127cdf0e10cSrcweir // 128cdf0e10cSrcweir 129cdf0e10cSrcweir 130cdf0e10cSrcweir 131cdf0e10cSrcweir /** Delegate the request to the parent and then register listeners at 132cdf0e10cSrcweir the child and add the child to the canvas. 133cdf0e10cSrcweir */ getChild(Object aParent, int nIndex)134cdf0e10cSrcweir public Object getChild (Object aParent, int nIndex) 135cdf0e10cSrcweir { 136cdf0e10cSrcweir AccessibleTreeNode aChild = (AccessibleTreeNode)super.getChild (aParent, nIndex); 137cdf0e10cSrcweir 138cdf0e10cSrcweir if (aChild == null) 139cdf0e10cSrcweir System.out.println ("getChild: child not found"); 140cdf0e10cSrcweir else 141cdf0e10cSrcweir // Keep translation table up-to-date. 142cdf0e10cSrcweir addNode (aChild); 143cdf0e10cSrcweir 144cdf0e10cSrcweir return aChild; 145cdf0e10cSrcweir } 146cdf0e10cSrcweir getChildNoCreate(Object aParent, int nIndex)147cdf0e10cSrcweir public Object getChildNoCreate (Object aParent, int nIndex) 148cdf0e10cSrcweir { 149cdf0e10cSrcweir AccessibleTreeNode aChild = (AccessibleTreeNode)super.getChildNoCreate (aParent, nIndex); 150cdf0e10cSrcweir 151cdf0e10cSrcweir return aChild; 152cdf0e10cSrcweir } 153cdf0e10cSrcweir 154cdf0e10cSrcweir 155cdf0e10cSrcweir 156cdf0e10cSrcweir 157cdf0e10cSrcweir /** Remove a node (and all children) from the tree model. 158cdf0e10cSrcweir */ removeChild(AccessibleTreeNode aNode)159cdf0e10cSrcweir protected boolean removeChild (AccessibleTreeNode aNode) 160cdf0e10cSrcweir { 161cdf0e10cSrcweir try 162cdf0e10cSrcweir { 163cdf0e10cSrcweir if( aNode == null ) 164cdf0e10cSrcweir { 165cdf0e10cSrcweir System.out.println ("can't remove null node"); 166cdf0e10cSrcweir return false; 167cdf0e10cSrcweir } 168cdf0e10cSrcweir else 169cdf0e10cSrcweir { 170cdf0e10cSrcweir // depth-first removal of children 171cdf0e10cSrcweir while (aNode.getChildCount() > 0) 172cdf0e10cSrcweir if ( ! removeChild (aNode.getChildNoCreate (0))) 173cdf0e10cSrcweir break; 174cdf0e10cSrcweir 175cdf0e10cSrcweir // Remove node from its parent. 176cdf0e10cSrcweir AccessibleTreeNode aParent = aNode.getParent(); 177cdf0e10cSrcweir if (aParent != null) 178cdf0e10cSrcweir { 179cdf0e10cSrcweir int nIndex = aParent.indexOf(aNode); 180cdf0e10cSrcweir aParent.removeChild (nIndex); 181cdf0e10cSrcweir } 182cdf0e10cSrcweir 183cdf0e10cSrcweir maNodeMap.RemoveNode (aNode); 184cdf0e10cSrcweir } 185cdf0e10cSrcweir } 186cdf0e10cSrcweir catch (Exception e) 187cdf0e10cSrcweir { 188cdf0e10cSrcweir System.out.println ("caught exception while removing child " 189cdf0e10cSrcweir + aNode + " : " + e); 190cdf0e10cSrcweir e.printStackTrace (); 191cdf0e10cSrcweir return false; 192cdf0e10cSrcweir } 193cdf0e10cSrcweir return true; 194cdf0e10cSrcweir } 195cdf0e10cSrcweir removeNode(XAccessibleContext xNode)196cdf0e10cSrcweir public void removeNode (XAccessibleContext xNode) 197cdf0e10cSrcweir { 198cdf0e10cSrcweir if (xNode != null) 199cdf0e10cSrcweir { 200cdf0e10cSrcweir AccessibleTreeNode aNode = maNodeMap.GetNode (xNode); 201cdf0e10cSrcweir AccessibleTreeNode aRootNode = (AccessibleTreeNode)getRoot(); 202cdf0e10cSrcweir TreeModelEvent aEvent = createEvent (aRootNode, aNode); 203cdf0e10cSrcweir removeChild (aNode); 204cdf0e10cSrcweir if (mbVerbose) 205cdf0e10cSrcweir System.out.println (aNode); 206cdf0e10cSrcweir fireTreeNodesRemoved (aEvent); 207cdf0e10cSrcweir maCanvas.repaint (); 208cdf0e10cSrcweir } 209cdf0e10cSrcweir } 210cdf0e10cSrcweir 211cdf0e10cSrcweir 212cdf0e10cSrcweir /** Add add a new child to a parent. 213cdf0e10cSrcweir @return 214cdf0e10cSrcweir Returns the new or existing representation of the specified 215cdf0e10cSrcweir accessible object. 216cdf0e10cSrcweir */ addChild(AccTreeNode aParentNode, XAccessible xNewChild)217cdf0e10cSrcweir protected AccessibleTreeNode addChild (AccTreeNode aParentNode, XAccessible xNewChild) 218cdf0e10cSrcweir { 219cdf0e10cSrcweir AccessibleTreeNode aChildNode = null; 220cdf0e10cSrcweir try 221cdf0e10cSrcweir { 222cdf0e10cSrcweir boolean bRet = false; 223cdf0e10cSrcweir 224cdf0e10cSrcweir // First make sure that the accessible object does not already have 225cdf0e10cSrcweir // a representation. 226cdf0e10cSrcweir aChildNode = maNodeMap.GetNode(xNewChild); 227cdf0e10cSrcweir if (aChildNode == null) 228cdf0e10cSrcweir aChildNode = aParentNode.addAccessibleChild (xNewChild); 229cdf0e10cSrcweir else 230cdf0e10cSrcweir System.out.println ("node already present"); 231cdf0e10cSrcweir } 232cdf0e10cSrcweir catch (Exception e) 233cdf0e10cSrcweir { 234cdf0e10cSrcweir System.out.println ("caught exception while adding child " 235cdf0e10cSrcweir + xNewChild + " to parent " + aParentNode + ": " + e); 236cdf0e10cSrcweir e.printStackTrace (); 237cdf0e10cSrcweir } 238cdf0e10cSrcweir return aChildNode; 239cdf0e10cSrcweir } 240cdf0e10cSrcweir addChild(XAccessibleContext xParent, XAccessible xChild)241cdf0e10cSrcweir public void addChild (XAccessibleContext xParent, XAccessible xChild) 242cdf0e10cSrcweir { 243cdf0e10cSrcweir AccessibleTreeNode aParentNode = maNodeMap.GetNode (xParent); 244cdf0e10cSrcweir if (aParentNode instanceof AccTreeNode) 245cdf0e10cSrcweir { 246cdf0e10cSrcweir AccessibleTreeNode aChild = addChild ((AccTreeNode)aParentNode, xChild); 247cdf0e10cSrcweir if (addNode (aChild)) 248cdf0e10cSrcweir { 249cdf0e10cSrcweir if (maCanvas != null) 250cdf0e10cSrcweir maCanvas.updateNode ((AccTreeNode)aParentNode); 251cdf0e10cSrcweir 252cdf0e10cSrcweir // A call to fireTreeNodesInserted for xNew 253cdf0e10cSrcweir // should be sufficient but at least the 254cdf0e10cSrcweir // StringNode object that contains the number of 255cdf0e10cSrcweir // children also changes and we do not know its 256cdf0e10cSrcweir // index relative to its parent. Therefore the 257cdf0e10cSrcweir // more expensive fireTreeStructureChanged is 258cdf0e10cSrcweir // necessary. 259cdf0e10cSrcweir fireTreeNodesInserted (createEvent (xParent, xChild)); 260cdf0e10cSrcweir updateNode (xParent, AccessibleTreeHandler.class); 261cdf0e10cSrcweir } 262cdf0e10cSrcweir maCanvas.repaint (); 263cdf0e10cSrcweir } 264cdf0e10cSrcweir } 265cdf0e10cSrcweir 266cdf0e10cSrcweir 267cdf0e10cSrcweir /** Add the child node to the internal tree structure. 268cdf0e10cSrcweir @param aNode 269cdf0e10cSrcweir The node to insert into the internal tree structure. 270cdf0e10cSrcweir */ addNode(AccessibleTreeNode aNode)271cdf0e10cSrcweir protected boolean addNode (AccessibleTreeNode aNode) 272cdf0e10cSrcweir { 273cdf0e10cSrcweir boolean bRet = false; 274cdf0e10cSrcweir try 275cdf0e10cSrcweir { 276cdf0e10cSrcweir if ( ! maNodeMap.ValueIsMember (aNode)) 277cdf0e10cSrcweir { 278cdf0e10cSrcweir if (aNode instanceof AccTreeNode) 279cdf0e10cSrcweir { 280cdf0e10cSrcweir AccTreeNode aChild = (AccTreeNode)aNode; 281cdf0e10cSrcweir XAccessibleContext xChild = aChild.getContext(); 282cdf0e10cSrcweir registerAccListener (aChild); 283cdf0e10cSrcweir if (maCanvas != null) 284cdf0e10cSrcweir maCanvas.addNode (aChild); 285cdf0e10cSrcweir maNodeMap.InsertNode (xChild, aChild); 286cdf0e10cSrcweir } 287cdf0e10cSrcweir bRet = true; 288cdf0e10cSrcweir } 289cdf0e10cSrcweir 290cdf0e10cSrcweir } 291cdf0e10cSrcweir catch (Exception e) 292cdf0e10cSrcweir { 293cdf0e10cSrcweir System.out.println ("caught exception while adding node " 294cdf0e10cSrcweir + aNode + ": " + e); 295cdf0e10cSrcweir e.printStackTrace (); 296cdf0e10cSrcweir } 297cdf0e10cSrcweir return bRet; 298cdf0e10cSrcweir } 299cdf0e10cSrcweir 300cdf0e10cSrcweir 301cdf0e10cSrcweir 302cdf0e10cSrcweir 303cdf0e10cSrcweir /** create path to node, suitable for TreeModelEvent constructor 304cdf0e10cSrcweir * @see javax.swing.event.TreeModelEvent#TreeModelEvent 305cdf0e10cSrcweir */ createPath(AccessibleTreeNode aNode)306cdf0e10cSrcweir protected Object[] createPath (AccessibleTreeNode aNode) 307cdf0e10cSrcweir { 308cdf0e10cSrcweir Vector aPath = new Vector(); 309cdf0e10cSrcweir aNode.createPath (aPath); 310cdf0e10cSrcweir return aPath.toArray(); 311cdf0e10cSrcweir } 312cdf0e10cSrcweir 313cdf0e10cSrcweir // 314cdf0e10cSrcweir // listeners (and helper methods) 315cdf0e10cSrcweir // 316cdf0e10cSrcweir // We are registered with listeners as soon as objects are in the 317cdf0e10cSrcweir // tree cache, and we should get removed as soon as they are out. 318cdf0e10cSrcweir // 319cdf0e10cSrcweir fireTreeNodesChanged(TreeModelEvent e)320cdf0e10cSrcweir protected void fireTreeNodesChanged(TreeModelEvent e) 321cdf0e10cSrcweir { 322cdf0e10cSrcweir for(int i = 0; i < maTMListeners.size(); i++) 323cdf0e10cSrcweir { 324cdf0e10cSrcweir ((TreeModelListener)maTMListeners.get(i)).treeNodesChanged(e); 325cdf0e10cSrcweir } 326cdf0e10cSrcweir } 327cdf0e10cSrcweir fireTreeNodesInserted(final TreeModelEvent e)328cdf0e10cSrcweir protected void fireTreeNodesInserted(final TreeModelEvent e) 329cdf0e10cSrcweir { 330cdf0e10cSrcweir for(int i = 0; i < maTMListeners.size(); i++) 331cdf0e10cSrcweir { 332cdf0e10cSrcweir ((TreeModelListener)maTMListeners.get(i)).treeNodesInserted(e); 333cdf0e10cSrcweir } 334cdf0e10cSrcweir } 335cdf0e10cSrcweir fireTreeNodesRemoved(final TreeModelEvent e)336cdf0e10cSrcweir protected void fireTreeNodesRemoved(final TreeModelEvent e) 337cdf0e10cSrcweir { 338cdf0e10cSrcweir for(int i = 0; i < maTMListeners.size(); i++) 339cdf0e10cSrcweir { 340cdf0e10cSrcweir ((TreeModelListener)maTMListeners.get(i)).treeNodesRemoved(e); 341cdf0e10cSrcweir } 342cdf0e10cSrcweir } 343cdf0e10cSrcweir fireTreeStructureChanged(final TreeModelEvent e)344cdf0e10cSrcweir protected void fireTreeStructureChanged(final TreeModelEvent e) 345cdf0e10cSrcweir { 346cdf0e10cSrcweir for(int i = 0; i < maTMListeners.size(); i++) 347cdf0e10cSrcweir { 348cdf0e10cSrcweir ((TreeModelListener)maTMListeners.get(i)).treeStructureChanged(e); 349cdf0e10cSrcweir } 350cdf0e10cSrcweir } 351cdf0e10cSrcweir createEvent(XAccessibleContext xParent)352cdf0e10cSrcweir protected TreeModelEvent createEvent (XAccessibleContext xParent) 353cdf0e10cSrcweir { 354cdf0e10cSrcweir AccessibleTreeNode aParentNode = maNodeMap.GetNode (xParent); 355cdf0e10cSrcweir return new TreeModelEvent (this, createPath (aParentNode)); 356cdf0e10cSrcweir } 357cdf0e10cSrcweir 358cdf0e10cSrcweir /** Create a TreeModelEvent object that informs listeners that one child 359cdf0e10cSrcweir has been removed from or inserted into its parent. 360cdf0e10cSrcweir */ createEvent(XAccessibleContext xParent, XAccessible xChild)361cdf0e10cSrcweir public TreeModelEvent createEvent (XAccessibleContext xParent, XAccessible xChild) 362cdf0e10cSrcweir { 363cdf0e10cSrcweir AccessibleTreeNode aParentNode = maNodeMap.GetNode (xParent); 364cdf0e10cSrcweir return createEvent (aParentNode, xParent); 365cdf0e10cSrcweir } 366cdf0e10cSrcweir createEvent(AccessibleTreeNode aParentNode, XAccessibleContext xChild)367cdf0e10cSrcweir public TreeModelEvent createEvent (AccessibleTreeNode aParentNode, XAccessibleContext xChild) 368cdf0e10cSrcweir { 369cdf0e10cSrcweir AccessibleTreeNode aChildNode = null; 370cdf0e10cSrcweir if (xChild != null) 371cdf0e10cSrcweir aChildNode = maNodeMap.GetNode (xChild); 372cdf0e10cSrcweir return createEvent (aParentNode, aChildNode); 373cdf0e10cSrcweir } 374cdf0e10cSrcweir 375cdf0e10cSrcweir 376cdf0e10cSrcweir createEvent( AccessibleTreeNode aParentNode, AccessibleTreeNode aChildNode)377cdf0e10cSrcweir protected TreeModelEvent createEvent ( 378cdf0e10cSrcweir AccessibleTreeNode aParentNode, 379cdf0e10cSrcweir AccessibleTreeNode aChildNode) 380cdf0e10cSrcweir { 381cdf0e10cSrcweir Object[] aPathToParent = createPath (aParentNode); 382cdf0e10cSrcweir 383cdf0e10cSrcweir int nIndexInParent = -1; 384cdf0e10cSrcweir if (aChildNode != null) 385cdf0e10cSrcweir nIndexInParent = aParentNode.indexOf (aChildNode); 386cdf0e10cSrcweir if (mbVerbose) 387cdf0e10cSrcweir System.out.println (aChildNode + " " + nIndexInParent); 388cdf0e10cSrcweir 389cdf0e10cSrcweir if (nIndexInParent == -1) 390cdf0e10cSrcweir // This event may be passed only to treeStructureChanged of the listeners. 391cdf0e10cSrcweir return new TreeModelEvent (this, 392cdf0e10cSrcweir aPathToParent); 393cdf0e10cSrcweir else 394cdf0e10cSrcweir // General purpose event for removing or inserting known nodes. 395cdf0e10cSrcweir return new TreeModelEvent (this, 396cdf0e10cSrcweir aPathToParent, 397cdf0e10cSrcweir new int[] {nIndexInParent}, 398cdf0e10cSrcweir new Object[] {aChildNode} ); 399cdf0e10cSrcweir } 400cdf0e10cSrcweir 401cdf0e10cSrcweir 402cdf0e10cSrcweir 403cdf0e10cSrcweir 404cdf0e10cSrcweir /** Create a TreeModelEvent that indicates changes at those children of 405cdf0e10cSrcweir the specified node with the specified indices. 406cdf0e10cSrcweir */ createChangeEvent(AccTreeNode aNode, Vector aChildIndices)407cdf0e10cSrcweir protected TreeModelEvent createChangeEvent (AccTreeNode aNode, Vector aChildIndices) 408cdf0e10cSrcweir { 409cdf0e10cSrcweir // Build a list of child objects that are indicated by the given indices. 410cdf0e10cSrcweir int nCount = aChildIndices.size(); 411cdf0e10cSrcweir Object aChildObjects[] = new Object[nCount]; 412cdf0e10cSrcweir int nChildIndices[] = new int[nCount]; 413cdf0e10cSrcweir for (int i=0; i<nCount; i++) 414cdf0e10cSrcweir { 415cdf0e10cSrcweir int nIndex = ((Integer)aChildIndices.elementAt(i)).intValue(); 416cdf0e10cSrcweir aChildObjects[i] = aNode.getChild (nIndex); 417cdf0e10cSrcweir nChildIndices[i] = nIndex; 418cdf0e10cSrcweir } 419cdf0e10cSrcweir 420cdf0e10cSrcweir return new TreeModelEvent (this, 421cdf0e10cSrcweir createPath(aNode), 422cdf0e10cSrcweir nChildIndices, 423cdf0e10cSrcweir aChildObjects); 424cdf0e10cSrcweir } 425cdf0e10cSrcweir 426cdf0e10cSrcweir 427cdf0e10cSrcweir 428cdf0e10cSrcweir /** 429cdf0e10cSrcweir * broadcast a tree event in a seperate Thread 430cdf0e10cSrcweir * must override fire method 431cdf0e10cSrcweir */ 432cdf0e10cSrcweir class EventRunner implements Runnable 433cdf0e10cSrcweir { run()434cdf0e10cSrcweir public void run() 435cdf0e10cSrcweir { 436cdf0e10cSrcweir for(int i = 0; i < maTMListeners.size(); i++) 437cdf0e10cSrcweir { 438cdf0e10cSrcweir fire( (TreeModelListener)maTMListeners.get(i) ); 439cdf0e10cSrcweir } 440cdf0e10cSrcweir } 441cdf0e10cSrcweir fire( TreeModelListener l)442cdf0e10cSrcweir protected void fire( TreeModelListener l) { } 443cdf0e10cSrcweir } 444cdf0e10cSrcweir 445cdf0e10cSrcweir 446cdf0e10cSrcweir getBroadcaster(Object aObject)447cdf0e10cSrcweir protected XAccessibleEventBroadcaster getBroadcaster (Object aObject) 448cdf0e10cSrcweir { 449cdf0e10cSrcweir if (aObject instanceof AccTreeNode) 450cdf0e10cSrcweir return (XAccessibleEventBroadcaster) UnoRuntime.queryInterface ( 451cdf0e10cSrcweir XAccessibleEventBroadcaster.class, ((AccTreeNode)aObject).getContext()); 452cdf0e10cSrcweir else 453cdf0e10cSrcweir return null; 454cdf0e10cSrcweir } 455cdf0e10cSrcweir registerAccListener( Object aObject )456cdf0e10cSrcweir protected void registerAccListener( Object aObject ) 457cdf0e10cSrcweir { 458cdf0e10cSrcweir // register this as listener for XAccessibleEventBroadcaster 459cdf0e10cSrcweir // implementations 460cdf0e10cSrcweir XAccessibleEventBroadcaster xBroadcaster = getBroadcaster( aObject ); 461cdf0e10cSrcweir if (xBroadcaster != null) 462cdf0e10cSrcweir { 463cdf0e10cSrcweir xBroadcaster.addEventListener( mxListener ); 464cdf0e10cSrcweir } 465cdf0e10cSrcweir } 466cdf0e10cSrcweir removeAccListener( Object aObject )467cdf0e10cSrcweir protected void removeAccListener( Object aObject ) 468cdf0e10cSrcweir { 469cdf0e10cSrcweir XAccessibleEventBroadcaster xBroadcaster = getBroadcaster( aObject ); 470cdf0e10cSrcweir if (xBroadcaster != null) 471cdf0e10cSrcweir { 472cdf0e10cSrcweir xBroadcaster.removeEventListener( mxListener ); 473cdf0e10cSrcweir } 474cdf0e10cSrcweir } 475cdf0e10cSrcweir 476cdf0e10cSrcweir 477cdf0e10cSrcweir setCanvas(Canvas aCanvas)478cdf0e10cSrcweir public void setCanvas (Canvas aCanvas) 479cdf0e10cSrcweir { 480cdf0e10cSrcweir maCanvas = aCanvas; 481cdf0e10cSrcweir } 482cdf0e10cSrcweir getCanvas()483cdf0e10cSrcweir public Canvas getCanvas () 484cdf0e10cSrcweir { 485cdf0e10cSrcweir return maCanvas; 486cdf0e10cSrcweir } 487cdf0e10cSrcweir updateNode(XAccessibleContext xSource, java.lang.Class class1)488cdf0e10cSrcweir public void updateNode (XAccessibleContext xSource, java.lang.Class class1) 489cdf0e10cSrcweir { 490cdf0e10cSrcweir updateNode (xSource, class1,null); 491cdf0e10cSrcweir } 492cdf0e10cSrcweir 493cdf0e10cSrcweir /** Get a list of children of the node associated with xSource that are 494cdf0e10cSrcweir affected by the given handlers. Fire events that these children may 495cdf0e10cSrcweir have changed in the tree view. Update the canvas representation of 496cdf0e10cSrcweir xSource. 497cdf0e10cSrcweir */ updateNode(XAccessibleContext xSource, java.lang.Class class1, java.lang.Class class2)498cdf0e10cSrcweir public AccTreeNode updateNode (XAccessibleContext xSource, 499cdf0e10cSrcweir java.lang.Class class1, java.lang.Class class2) 500cdf0e10cSrcweir { 501cdf0e10cSrcweir AccessibleTreeNode aTreeNode = maNodeMap.GetNode (xSource); 502cdf0e10cSrcweir AccTreeNode aNode = null; 503cdf0e10cSrcweir if (mbVerbose) 504cdf0e10cSrcweir System.out.println ("updating node " + xSource + " " + aTreeNode); 505cdf0e10cSrcweir if (aTreeNode instanceof AccTreeNode) 506cdf0e10cSrcweir { 507cdf0e10cSrcweir aNode = (AccTreeNode) aTreeNode; 508cdf0e10cSrcweir // Get list of affected children. 509cdf0e10cSrcweir Vector aChildIndices = (aNode).updateChildren ( 510cdf0e10cSrcweir class1, class2); 511cdf0e10cSrcweir // Fire events that these children may have changed. 512cdf0e10cSrcweir fireTreeNodesChanged ( 513cdf0e10cSrcweir createChangeEvent (aNode, aChildIndices)); 514cdf0e10cSrcweir } 515cdf0e10cSrcweir return aNode; 516cdf0e10cSrcweir } 517cdf0e10cSrcweir 518cdf0e10cSrcweir /** The listener to be registered with the accessible objects. 519cdf0e10cSrcweir * Could be set to 'this' for same-thread event delivery, or to an 520cdf0e10cSrcweir * instance of QueuedListener for multi-threaded delivery. May 521cdf0e10cSrcweir * not be changed, since this would trip the 522cdf0e10cSrcweir * register/removeAccListener logic. */ 523cdf0e10cSrcweir private final XAccessibleEventListener mxListener; 524cdf0e10cSrcweir 525cdf0e10cSrcweir // Map to translate from accessible object to corresponding tree node. 526cdf0e10cSrcweir private NodeMap maNodeMap; 527cdf0e10cSrcweir 528cdf0e10cSrcweir // If the lock count is higher then zero, then no events are processed. 529cdf0e10cSrcweir private int mnLockCount; 530cdf0e10cSrcweir 531cdf0e10cSrcweir private Canvas maCanvas; 532cdf0e10cSrcweir 533cdf0e10cSrcweir private EventListener maEventListener; 534cdf0e10cSrcweir } 535