diff options
author | Vladimir Glazounov <vg@openoffice.org> | 2003-04-11 16:07:28 +0000 |
---|---|---|
committer | Vladimir Glazounov <vg@openoffice.org> | 2003-04-11 16:07:28 +0000 |
commit | 96c9f5922a3bb2fc78914dfb5d834166920f4b23 (patch) | |
tree | a6ef6589a9ace3c9e030a8085668ab09ebc16931 /toolkit/test/accessibility/AccessibilityTreeModel.java | |
parent | a67795286698f991aae562185c62ba82be5fab61 (diff) |
INTEGRATION: CWS vcl07 (1.19.64); FILE MERGED
2003/04/08 14:28:24 obr 1.19.64.1: re-added accessibility workbench
Diffstat (limited to 'toolkit/test/accessibility/AccessibilityTreeModel.java')
-rw-r--r-- | toolkit/test/accessibility/AccessibilityTreeModel.java | 799 |
1 files changed, 170 insertions, 629 deletions
diff --git a/toolkit/test/accessibility/AccessibilityTreeModel.java b/toolkit/test/accessibility/AccessibilityTreeModel.java index d627757d6b7e..9e7365bfac2c 100644 --- a/toolkit/test/accessibility/AccessibilityTreeModel.java +++ b/toolkit/test/accessibility/AccessibilityTreeModel.java @@ -1,13 +1,11 @@ - -import javax.swing.tree.TreeModel; -import javax.swing.tree.TreePath; -import javax.swing.event.TreeModelListener; import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.tree.TreePath; + import java.util.Vector; import java.util.HashMap; import java.util.Enumeration; -import java.util.LinkedList; import drafts.com.sun.star.accessibility.*; @@ -19,61 +17,26 @@ import com.sun.star.lang.XServiceInfo; import com.sun.star.lang.XServiceName; public class AccessibilityTreeModel - implements TreeModel, XAccessibleEventListener + extends AccessibilityTreeModelBase { - // Map to translate from accessible object to corresponding tree node. - protected HashMap maXAccessibleToNode; - - // Making both of these static is clearly a hack. - protected static MessageInterface maMessageArea; - protected static Print maPrinter; - protected static boolean mbVerbose = true; + public boolean mbVerbose = false; - // If the lock count is higher then zero, then no events are processed. - private int mnLockCount; - - // The list of TreeModelListener objects. - private Vector maTMListeners; - - // The root node of the tree. Use setRoot to change it. - private AccessibleTreeNode maRoot = null; - - // default handlers - private static Vector aDefaultHandlers; - private static NodeHandler maContextHandler = new AccessibleContextHandler(); - private static NodeHandler maTextHandler = new AccessibleTextHandler(); - private static NodeHandler maEditableTextHandler = new AccessibleEditableTextHandler(); - private static NodeHandler maComponentHandler = new AccessibleComponentHandler(); - private static NodeHandler maExtendedComponentHandler = new AccessibleExtendedComponentHandler(); - private static NodeHandler maActionHandler = new AccessibleActionHandler(); - private static NodeHandler maImageHandler = new AccessibleImageHandler(); - private static NodeHandler maTableHandler = new AccessibleTableHandler(); - private static NodeHandler maCellHandler = new AccessibleCellHandler(); - private static NodeHandler maHypertextHandler = new AccessibleHypertextHandler(); - private static NodeHandler maHyperlinkHandler = new AccessibleHyperlinkHandler(); - private static NodeHandler maSelectionHandler = new AccessibleSelectionHandler(); - private static NodeHandler maRelationHandler = new AccessibleRelationHandler(); - private static NodeHandler maTreeHandler = new AccessibleTreeHandler(); - - private Canvas maCanvas; - - - public AccessibilityTreeModel (AccessibleTreeNode aRoot, MessageInterface aMessageArea, Print aPrinter) + public AccessibilityTreeModel (AccessibleTreeNode aRoot) { // create default node (unless we have a 'proper' node) if( ! (aRoot instanceof AccessibleTreeNode) ) aRoot = new StringNode ("Root", null); setRoot (aRoot); - maMessageArea = aMessageArea; - maPrinter = aPrinter; - maTMListeners = new Vector(); - maXAccessibleToNode = new HashMap (); + maNodeMap = new NodeMap(); + + maEventListener = new EventListener (this); + mxListener = new QueuedListener (maEventListener); + } - // syncronous or asyncronous event delivery? (i.e. same thread - // or in s seperate event delivery thread) - // xListener = this; // syncronous event delivery - xListener = new QueuedListener(); // asyncronous event delivery + public void clear () + { + maNodeMap.Clear(); } /** Lock the tree. While the tree is locked, events from the outside are @@ -82,7 +45,6 @@ public class AccessibilityTreeModel public void lock () { mnLockCount += 1; - System.out.println ("locking: " + mnLockCount); } /** Unlock the tree. After unlocking the tree as many times as locking @@ -94,127 +56,81 @@ public class AccessibilityTreeModel public void unlock (AccessibleTreeNode aNodeHint) { mnLockCount -= 1; - System.out.println ("unlocking: " + mnLockCount); if (mnLockCount == 0) - { fireTreeStructureChanged ( new TreeModelEvent (this, new TreePath (aNodeHint.createPath()))); - } } - public Object getRoot() + + + + /** Inform all listeners (especially the renderer) of a change of the + tree's structure. + @param aNode This node specifies the sub tree in which all changes + take place. + */ + public void FireTreeStructureChanged (AccessibleTreeNode aNode) { - return maRoot; } + + + + public synchronized void setRoot (AccessibleTreeNode aRoot) { - if (maRoot == null) - maRoot = aRoot; + if (getRoot() == null) + super.setRoot (aRoot); else { lock (); - clear (); - maRoot = aRoot; - unlock (maRoot); + maNodeMap.ForEach (new NodeMapCallback () { + public void Apply (AccTreeNode aNode) + { + if (maCanvas != null) + maCanvas.removeNode (aNode); + removeAccListener ((AccTreeNode)aNode); + } + }); + maNodeMap.Clear (); + + setRoot (aRoot); + unlock (aRoot); } } - /** Clears the model. That removes all nodes from the internal structures. - */ - public void clear () - { - System.out.println ("clearing the whole tree"); - Object[] aNodes = maXAccessibleToNode.values().toArray(); - for (int i=0; i<aNodes.length; i++) - removeNode ((AccessibleTreeNode)aNodes[i]); - } // // child management: // - public int getChildCount(Object aParent) - { - return (aParent instanceof AccessibleTreeNode) ? - ((AccessibleTreeNode)aParent).getChildCount() : 0; - } - public Object getChild (Object aParent, int nIndex) - { - Object aChild = null; - try - { - if (aParent instanceof AccessibleTreeNode) - aChild = getChild ((AccessibleTreeNode)aParent, nIndex); - else - System.out.println ("getChild called for unknown parent node"); - } - catch (com.sun.star.lang.IndexOutOfBoundsException e) - { - aChild = ("no child " + nIndex + " from " + aParent + ": " + e); - } - return aChild; - } /** Delegate the request to the parent and then register listeners at the child and add the child to the canvas. */ - public AccessibleTreeNode getChild (AccessibleTreeNode aParent, int nIndex) - throws com.sun.star.lang.IndexOutOfBoundsException + public Object getChild (Object aParent, int nIndex) { - AccessibleTreeNode aChild = null; - if (aParent != null) - aChild = aParent.getChild(nIndex); - - // Keep translation table up-to-date. - addNode (aChild); + AccessibleTreeNode aChild = (AccessibleTreeNode)super.getChild (aParent, nIndex); if (aChild == null) System.out.println ("getChild: child not found"); + else + // Keep translation table up-to-date. + addNode (aChild); return aChild; } - /** iterate over all children and look for child */ - public int getIndexOfChild (Object aParent, Object aChild) + public Object getChildNoCreate (Object aParent, int nIndex) { - int nIndex = -1; - try - { - if ((aParent instanceof AccessibleTreeNode) && (aChild instanceof AccessibleTreeNode)) - { - AccessibleTreeNode aParentNode = (AccessibleTreeNode) aParent; - AccessibleTreeNode aChildNode = (AccessibleTreeNode) aChild; + AccessibleTreeNode aChild = (AccessibleTreeNode)super.getChildNoCreate (aParent, nIndex); - int nChildCount = aParentNode.getChildCount(); - for( int i = 0; i < nChildCount; i++ ) - { - if (aChildNode.equals (aParentNode.getChild (i))) - { - nIndex = i; - break; - } - } - } - } - catch (com.sun.star.lang.IndexOutOfBoundsException e) - { - // Return -1 by falling through. - } - - // not found? - return nIndex; + return aChild; } - public boolean isLeaf (Object aNode) - { - return (aNode instanceof AccessibleTreeNode) ? - ((AccessibleTreeNode)aNode).isLeaf() : true; - } - /** Remove a node (and all children) from the tree model. @@ -232,7 +148,7 @@ public class AccessibilityTreeModel { // depth-first removal of children while (aNode.getChildCount() > 0) - if ( ! removeChild (aNode.getChild (0))) + if ( ! removeChild (aNode.getChildNoCreate (0))) break; // Remove node from its parent. @@ -243,35 +159,35 @@ public class AccessibilityTreeModel aParent.removeChild (nIndex); } - removeNode (aNode); + maNodeMap.RemoveNode (aNode); } } catch (Exception e) { - System.out.println ("caught exception while removing child " + aNode + " : " + e); + System.out.println ("caught exception while removing child " + + aNode + " : " + e); + e.printStackTrace (); return false; } return true; } - protected void removeNode (AccessibleTreeNode aNode) + public void removeNode (XAccessibleContext xNode) { - try - { - if ((aNode != null) && (aNode instanceof AccTreeNode)) - { - // Remove node itself from internal data structures. - removeFromCanvas ((AccTreeNode)aNode); - removeAccListener ((AccTreeNode)aNode); - maXAccessibleToNode.remove (((AccTreeNode)aNode).getAccessible()); - } - } - catch (Exception e) + if (xNode != null) { - System.out.println ("caught exception while removing node " + aNode + " : " + e); + AccessibleTreeNode aNode = maNodeMap.GetNode (xNode); + AccessibleTreeNode aRootNode = (AccessibleTreeNode)getRoot(); + TreeModelEvent aEvent = createEvent (aRootNode, aNode); + removeChild (aNode); + if (mbVerbose) + System.out.println (aNode); + fireTreeNodesRemoved (aEvent); + maCanvas.repaint (); } } + /** Add add a new child to a parent. @return Returns the new or existing representation of the specified @@ -286,7 +202,7 @@ public class AccessibilityTreeModel // First make sure that the accessible object does not already have // a representation. - aChildNode = (AccessibleTreeNode)maXAccessibleToNode.get (xNewChild); + aChildNode = maNodeMap.GetNode(xNewChild); if (aChildNode == null) aChildNode = aParentNode.addAccessibleChild (xNewChild); else @@ -294,12 +210,38 @@ public class AccessibilityTreeModel } catch (Exception e) { - System.out.println ("caught exception while adding child " + xNewChild - + " to parent " + aParentNode + ": " + e); + System.out.println ("caught exception while adding child " + + xNewChild + " to parent " + aParentNode + ": " + e); + e.printStackTrace (); } return aChildNode; } + public void addChild (XAccessibleContext xParent, XAccessible xChild) + { + AccessibleTreeNode aParentNode = maNodeMap.GetNode (xParent); + if (aParentNode instanceof AccTreeNode) + { + AccessibleTreeNode aChild = addChild ((AccTreeNode)aParentNode, xChild); + if (addNode (aChild)) + { + if (maCanvas != null) + maCanvas.updateNode ((AccTreeNode)aParentNode); + + // A call to fireTreeNodesInserted for xNew + // should be sufficient but at least the + // StringNode object that contains the number of + // children also changes and we do not know its + // index relative to its parent. Therefore the + // more expensive fireTreeStructureChanged is + // necessary. + fireTreeNodesInserted (createEvent (xParent, xChild)); + updateNode (xParent, AccessibleTreeHandler.class); + } + maCanvas.repaint (); + } + } + /** Add the child node to the internal tree structure. @param aNode @@ -310,15 +252,16 @@ public class AccessibilityTreeModel boolean bRet = false; try { - if (aNode instanceof AccTreeNode) + if ( ! maNodeMap.ValueIsMember (aNode)) { - AccTreeNode aChild = (AccTreeNode)aNode; - XAccessible xChild = aChild.getAccessible(); - if (maXAccessibleToNode.get (xChild) == null) + if (aNode instanceof AccTreeNode) { + AccTreeNode aChild = (AccTreeNode)aNode; + XAccessibleContext xChild = aChild.getContext(); registerAccListener (aChild); - maXAccessibleToNode.put (xChild, aChild); - addToCanvas (aChild); + if (maCanvas != null) + maCanvas.addNode (aChild); + maNodeMap.InsertNode (xChild, aChild); } bRet = true; } @@ -326,15 +269,15 @@ public class AccessibilityTreeModel } catch (Exception e) { - System.out.println ("caught exception while adding node " + aNode + ": " + e); + System.out.println ("caught exception while adding node " + + aNode + ": " + e); + e.printStackTrace (); } return bRet; } - protected AccessibleTreeNode getNode (XAccessible xAccessible) - { - return (AccessibleTreeNode)maXAccessibleToNode.get (xAccessible); - } + + /** create path to node, suitable for TreeModelEvent constructor * @see javax.swing.event.TreeModelEvent#TreeModelEvent @@ -353,19 +296,8 @@ public class AccessibilityTreeModel // tree cache, and we should get removed as soon as they are out. // - public void addTreeModelListener(TreeModelListener l) - { - maTMListeners.add(l); - } - - public void removeTreeModelListener(TreeModelListener l) - { - maTMListeners.remove(l); - } - protected void fireTreeNodesChanged(TreeModelEvent e) { - System.out.println("treeNodesChanges: " + e); for(int i = 0; i < maTMListeners.size(); i++) { ((TreeModelListener)maTMListeners.get(i)).treeNodesChanged(e); @@ -374,7 +306,6 @@ public class AccessibilityTreeModel protected void fireTreeNodesInserted(final TreeModelEvent e) { - System.out.println("treeNodesInserted: " + e); for(int i = 0; i < maTMListeners.size(); i++) { ((TreeModelListener)maTMListeners.get(i)).treeNodesInserted(e); @@ -383,7 +314,6 @@ public class AccessibilityTreeModel protected void fireTreeNodesRemoved(final TreeModelEvent e) { - System.out.println("treeNodesRemoved: " + e); for(int i = 0; i < maTMListeners.size(); i++) { ((TreeModelListener)maTMListeners.get(i)).treeNodesRemoved(e); @@ -392,35 +322,48 @@ public class AccessibilityTreeModel protected void fireTreeStructureChanged(final TreeModelEvent e) { - System.out.println("treeStructureChanged: " + e); for(int i = 0; i < maTMListeners.size(); i++) { ((TreeModelListener)maTMListeners.get(i)).treeStructureChanged(e); } } - protected TreeModelEvent createEvent (XAccessible xParent) + protected TreeModelEvent createEvent (XAccessibleContext xParent) { - AccessibleTreeNode aParentNode = (AccessibleTreeNode)maXAccessibleToNode.get (xParent); + AccessibleTreeNode aParentNode = maNodeMap.GetNode (xParent); return new TreeModelEvent (this, createPath (aParentNode)); } /** Create a TreeModelEvent object that informs listeners that one child has been removed from or inserted into its parent. */ - protected TreeModelEvent createEvent (XAccessible xParent, XAccessible xChild) + public TreeModelEvent createEvent (XAccessibleContext xParent, XAccessible xChild) { - // get parent node and create the tree path - AccessibleTreeNode aParentNode = (AccessibleTreeNode)maXAccessibleToNode.get (xParent); - System.out.println (xParent); - Object[] aPathToParent = createPath (aParentNode); + AccessibleTreeNode aParentNode = maNodeMap.GetNode (xParent); + return createEvent (aParentNode, xParent); + } + public TreeModelEvent createEvent (AccessibleTreeNode aParentNode, XAccessibleContext xChild) + { AccessibleTreeNode aChildNode = null; if (xChild != null) - aChildNode = (AccessibleTreeNode)maXAccessibleToNode.get (xChild); + aChildNode = maNodeMap.GetNode (xChild); + return createEvent (aParentNode, aChildNode); + } + + + + protected TreeModelEvent createEvent ( + AccessibleTreeNode aParentNode, + AccessibleTreeNode aChildNode) + { + Object[] aPathToParent = createPath (aParentNode); + int nIndexInParent = -1; - if (xChild != null) + if (aChildNode != null) nIndexInParent = aParentNode.indexOf (aChildNode); + if (mbVerbose) + System.out.println (aChildNode + " " + nIndexInParent); if (nIndexInParent == -1) // This event may be passed only to treeStructureChanged of the listeners. @@ -434,6 +377,9 @@ public class AccessibilityTreeModel new Object[] {aChildNode} ); } + + + /** Create a TreeModelEvent that indicates changes at those children of the specified node with the specified indices. */ @@ -475,12 +421,6 @@ public class AccessibilityTreeModel protected void fire( TreeModelListener l) { } } - /** The listener to be registered with the accessible objects. - * Could be set to 'this' for same-thread event delivery, or to an - * instance of QueuedListener for multi-threaded delivery. May - * not be changed, since this would trip the - * register/removeAccListener logic. */ - private final XAccessibleEventListener xListener; protected XAccessibleEventBroadcaster getBroadcaster (Object aObject) @@ -499,7 +439,7 @@ public class AccessibilityTreeModel XAccessibleEventBroadcaster xBroadcaster = getBroadcaster( aObject ); if (xBroadcaster != null) { - xBroadcaster.addEventListener( xListener ); + xBroadcaster.addEventListener( mxListener ); } } @@ -508,465 +448,66 @@ public class AccessibilityTreeModel XAccessibleEventBroadcaster xBroadcaster = getBroadcaster( aObject ); if (xBroadcaster != null) { - xBroadcaster.removeEventListener( xListener ); + xBroadcaster.removeEventListener( mxListener ); } } - // - // tree model edit - // - public void valueForPathChanged(TreePath path, Object newValue) { } - - // - // static methods + members for creating default nodes - // - - - - /** add default handlers based on the supported interfaces */ - public static void addDefaultHandlers (AccTreeNode aNode, XAccessibleContext xContext) + public void setCanvas (Canvas aCanvas) { - if (false) - { - // Slow but complete version: try each handler type separately. - aNode.addHandler (maContextHandler.createHandler (xContext)); - aNode.addHandler (maTextHandler.createHandler (xContext)); - aNode.addHandler (maEditableTextHandler.createHandler (xContext)); - aNode.addHandler (maComponentHandler.createHandler (xContext)); - aNode.addHandler (maExtendedComponentHandler.createHandler (xContext)); - aNode.addHandler (maActionHandler.createHandler (xContext)); - aNode.addHandler (maImageHandler.createHandler (xContext)); - aNode.addHandler (maTableHandler.createHandler (xContext)); - aNode.addHandler (maCellHandler.createHandler (xContext)); - aNode.addHandler (maHypertextHandler.createHandler (xContext)); - aNode.addHandler (maHyperlinkHandler.createHandler (xContext)); - aNode.addHandler (maSelectionHandler.createHandler (xContext)); - aNode.addHandler (maRelationHandler.createHandler (xContext)); - aNode.addHandler (maTreeHandler.createHandler (xContext)); - } - else - { - // Exploit dependencies between interfaces. - NodeHandler aHandler; - aNode.addHandler (maContextHandler.createHandler (xContext)); - - aHandler = maTextHandler.createHandler (xContext); - if (aHandler != null) - { - aNode.addHandler (aHandler); - aNode.addHandler (maEditableTextHandler.createHandler (xContext)); - aNode.addHandler (maHypertextHandler.createHandler (xContext)); - aNode.addHandler (maHyperlinkHandler.createHandler (xContext)); - } - aHandler = maComponentHandler.createHandler (xContext); - if (aHandler != null) - { - aNode.addHandler (aHandler); - aNode.addHandler (maExtendedComponentHandler.createHandler (xContext)); - } - aNode.addHandler (maActionHandler.createHandler (xContext)); - aNode.addHandler (maImageHandler.createHandler (xContext)); - aNode.addHandler (maTableHandler.createHandler (xContext)); - aNode.addHandler (maRelationHandler.createHandler (xContext)); - aNode.addHandler (maCellHandler.createHandler (xContext)); - aNode.addHandler (maSelectionHandler.createHandler (xContext)); - aNode.addHandler (maTreeHandler.createHandler (xContext)); - } + maCanvas = aCanvas; } - /** create a node with the default handlers */ - public static AccTreeNode createDefaultNode (XAccessible xAccessible, AccessibleTreeNode aParent) + public Canvas getCanvas () { - // default: aObject + aDisplay - String sDisplay; - - // if we are accessible, we use the context + name instead - XAccessibleContext xContext = null; - if (xAccessible != null) - xContext = xAccessible.getAccessibleContext(); - if (xContext != null) - { - sDisplay = xContext.getAccessibleName(); - if (sDisplay.length()==0) - { - sDisplay = "<no name>"; - // Try to determine some usefull name that indicates the - // function of the object in question. - XServiceName xSN = (XServiceName) UnoRuntime.queryInterface ( - XServiceName.class, xAccessible); - if (xSN != null) - sDisplay = xSN.getServiceName (); - else - { - XServiceInfo xSI = (XServiceInfo) UnoRuntime.queryInterface ( - XServiceInfo.class, xAccessible); - if (xSI != null) - sDisplay = xSI.getImplementationName (); - } - } - } - else - sDisplay = new String ("not accessible"); - - - // create node, and add default handlers - AccTreeNode aNode = new AccTreeNode (xAccessible, xContext, sDisplay, aParent); - AccessibilityTreeModel.addDefaultHandlers (aNode, xContext); - - if (mbVerbose) - maPrinter.print (". "); - - if (aNode == null) - System.out.println ("createDefaultNode == null"); - return aNode; + return maCanvas; } - - // - // XAccessibleEventListener interface - // - - private static String objectToString(Object aObject) + public void updateNode (XAccessibleContext xSource, java.lang.Class class1) { - if (aObject == null) - return null; - else - return aObject.toString(); - /* - if( aObject instanceof Any ) - aObject = ((Any)aObject).getObject(); - - if( aObject instanceof XInterface ) - { - XServiceInfo xInfo = - (XServiceInfo)UnoRuntime.queryInterface( XServiceInfo.class, - aObject); - aObject = (xInfo != null) ? xInfo.getImplementationName() - : aObject.getClass().toString(); - } - - return (aObject != null) ? aObject.toString() : null; - */ + updateNode (xSource, class1,null); } - public void disposing( EventObject aEvent) - { - System.out.println("dispose: " + objectToString(aEvent.Source)); - removeChild ((AccessibleTreeNode)maXAccessibleToNode.get (aEvent.Source)); - /* - if( knowsNode( aEvent.Source ) ) - { - System.out.println("ERROR: Dispose for living node called! " + - "Maybe notifications don't work?"); - removeNode( aEvent.Source ); -// fireTreeStructureChanged( createEvent( getRoot() ) ); - } - */ - } - private void handleEvent (XAccessible xSource, java.lang.Class class1) - { handleEvent (xSource, class1,null); } - private void handleEvent (XAccessible xSource, java.lang.Class class1, java.lang.Class class2) + /** Get a list of children of the node associated with xSource that are + affected by the given handlers. Fire events that these children may + have changed in the tree view. Update the canvas representation of + xSource. + */ + public AccTreeNode updateNode (XAccessibleContext xSource, + java.lang.Class class1, java.lang.Class class2) { - AccessibleTreeNode aNode = (AccessibleTreeNode)maXAccessibleToNode.get (xSource); - if (aNode instanceof AccTreeNode) + AccessibleTreeNode aTreeNode = maNodeMap.GetNode (xSource); + AccTreeNode aNode = null; + if (mbVerbose) + System.out.println ("updating node " + xSource + " " + aTreeNode); + if (aTreeNode instanceof AccTreeNode) { - Vector aChildIndices = ((AccTreeNode)aNode).update ( + aNode = (AccTreeNode) aTreeNode; + // Get list of affected children. + Vector aChildIndices = (aNode).updateChildren ( class1, class2); + // Fire events that these children may have changed. fireTreeNodesChanged ( - createChangeEvent ((AccTreeNode)aNode, aChildIndices)); - updateOnCanvas ((AccTreeNode)aNode); - maCanvas.repaint (); - } - } - - static final String[] aEventNames = - { - "[UNKNOWN]", "ACTION", "ACTIVE_DESCENDANT", "CARET", "CHILD", - "DESCRIPTION", "HYPERTEXT_OFFSET", "NAME", "SELECTION", "STATE", - "TABLE_CAPTION_CHANGED", "TABLE_COLUMN_DESCRIPTION_CHANGED", - "TABLE_COLUMN_HEADER_CHANGED", "TABLE_MODEL_CHANGED", - "TABLE_ROW_DESCRIPTION_CHANGED", "TABLE_ROW_HEADER_CHANGED", - "TABLE_SUMMARY_CHANGED", "TEXT", "VALUE", "VISIBLE_DATA", - "CONTROLLED_BY_PROPERTY", "CONTROLLER_FOR_PROPERTY", - "LABEL_FOR_PROPERTY", "LABELED_BY_PROPERTY", "MEMBER_OF_PROPERTY", - "CONTENT_FLOWS_FROM", "CONTENT_FLOWS_TO", - "[UNKNOWN]" - }; - - /** This method is called from accessible objects that broadcast - modifications of themselves or from their children. The event is - processed only, except printing some messages, if the tree is not - locked. It should be locked during changes to its internal - structure like expanding nodes. - */ - public void notifyEvent( AccessibleEventObject aEvent ) - { - - int nId = aEvent.EventId; - if( (nId < 0) || (nId >= aEventNames.length) ) - nId = 0; - - System.out.println( "notify: " + aEvent.EventId + " " - + aEventNames[nId] + ": [" - + objectToString(aEvent.Source) + "] " - + objectToString(aEvent.OldValue) + "->" - + objectToString(aEvent.NewValue) ); - - if (mnLockCount > 0) - { - System.out.println ("ignoring event because tree is locked"); - return; + createChangeEvent (aNode, aChildIndices)); } - - XAccessible xSource = (XAccessible)UnoRuntime.queryInterface( - XAccessible.class,aEvent.Source); - - switch( aEvent.EventId ) - { - case AccessibleEventId.ACCESSIBLE_CHILD_EVENT: - // fire insertion and deletion events: - if (aEvent.OldValue != null) - { - XAccessible xOld = (XAccessible)UnoRuntime.queryInterface( - XAccessible.class,aEvent.OldValue); - // Create event before removing the node to get the old - // index of the node. - TreeModelEvent aRemoveEvent = createEvent (xSource, xOld); - removeChild ((AccessibleTreeNode)maXAccessibleToNode.get (xOld)); - fireTreeNodesRemoved (aRemoveEvent); - handleEvent (xSource, AccessibleTreeHandler.class); - } - - // Insertion and removal of children should be mutually - // exclusive. But then there is this 'should' ... - if (aEvent.NewValue != null) - { - XAccessible xNew = (XAccessible)UnoRuntime.queryInterface( - XAccessible.class,aEvent.NewValue); - // Create event after inserting it so that its new index - // in the parent can be determined. - AccessibleTreeNode aParentNode = getNode (xSource); - if (aParentNode instanceof AccTreeNode) - { - AccessibleTreeNode aChild = addChild ((AccTreeNode)aParentNode, xNew); - if (addNode (aChild)) - { - // ((AccTreeNode)aParentNode).update (); - updateOnCanvas ((AccTreeNode)aParentNode); - - // A call to fireTreeNodesInserted for xNew - // should be sufficient but at least the - // StringNode object that contains the number of - // children also changes and we do not know its - // index relative to its parent. Therefore the - // more expensive fireTreeStructureChanged is - // necessary. - fireTreeNodesInserted (createEvent (xSource, xNew)); - handleEvent (xSource, AccessibleTreeHandler.class); - } - } - } - maCanvas.repaint (); - break; - - case AccessibleEventId.ACCESSIBLE_TABLE_MODEL_CHANGED: - AccessibleTableModelChange aModelChange = (AccessibleTableModelChange)aEvent.NewValue; - System.out.println( "Range: StartRow " + aModelChange.FirstRow + - " StartColumn " + aModelChange.FirstColumn + - " EndRow " + aModelChange.LastRow + - " EndColumn " + aModelChange.LastColumn + - " Id " + aModelChange.Type); - break; - - case AccessibleEventId.ACCESSIBLE_VISIBLE_DATA_EVENT: - handleEvent (xSource, - AccessibleComponentHandler.class, - AccessibleExtendedComponentHandler.class); - break; - - - case AccessibleEventId.ACCESSIBLE_NAME_EVENT: - case AccessibleEventId.ACCESSIBLE_DESCRIPTION_EVENT: - case AccessibleEventId.ACCESSIBLE_STATE_EVENT: - case AccessibleEventId.CONTROLLED_BY_PROPERTY: - case AccessibleEventId.CONTROLLER_FOR_PROPERTY: - case AccessibleEventId.LABEL_FOR_PROPERTY: - case AccessibleEventId.LABELED_BY_PROPERTY: - case AccessibleEventId.MEMBER_OF_PROPERTY: - case AccessibleEventId.ACCESSIBLE_SELECTION_EVENT: - handleEvent (xSource, AccessibleContextHandler.class); - break; - - case AccessibleEventId.ACCESSIBLE_TABLE_CAPTION_CHANGED: - case AccessibleEventId.ACCESSIBLE_TABLE_COLUMN_DESCRIPTION_CHANGED: - case AccessibleEventId.ACCESSIBLE_TABLE_COLUMN_HEADER_CHANGED: - case AccessibleEventId.ACCESSIBLE_TABLE_ROW_DESCRIPTION_CHANGED: - case AccessibleEventId.ACCESSIBLE_TABLE_ROW_HEADER_CHANGED: - case AccessibleEventId.ACCESSIBLE_TABLE_SUMMARY_CHANGED: - handleEvent (xSource, AccessibleTableHandler.class); - break; - - case AccessibleEventId.ACCESSIBLE_ACTION_EVENT: - handleEvent (xSource, AccessibleActionHandler.class); - break; - - case AccessibleEventId.ACCESSIBLE_HYPERTEXT_OFFSET: - handleEvent (xSource, AccessibleHypertextHandler.class); - break; - - case AccessibleEventId.ACCESSIBLE_ACTIVE_DESCENDANT_EVENT: - case AccessibleEventId.ACCESSIBLE_CARET_EVENT: - case AccessibleEventId.ACCESSIBLE_TEXT_EVENT: - case AccessibleEventId.ACCESSIBLE_VALUE_EVENT: - handleEvent (xSource, AccessibleTextHandler.class); - break; - - default: - break; - } - } - - - // - // canvas - // - - public void setCanvas( Canvas aCanvas ) - { - maCanvas = aCanvas; - } - - protected void addToCanvas (AccTreeNode aNode) - { - if (maCanvas != null) - maCanvas.addNode (aNode); - } - - protected void removeFromCanvas (AccTreeNode aNode) - { - if (maCanvas != null) - maCanvas.removeNode (aNode); - } - - protected void updateOnCanvas (AccTreeNode aNode) - { - if (maCanvas != null) - maCanvas.updateNode (aNode); + return aNode; } + /** The listener to be registered with the accessible objects. + * Could be set to 'this' for same-thread event delivery, or to an + * instance of QueuedListener for multi-threaded delivery. May + * not be changed, since this would trip the + * register/removeAccListener logic. */ + private final XAccessibleEventListener mxListener; + // Map to translate from accessible object to corresponding tree node. + private NodeMap maNodeMap; + // If the lock count is higher then zero, then no events are processed. + private int mnLockCount; + private Canvas maCanvas; - /** QueuedListener implements an AccessibleEventListener which - * delegates all events to another such listener, but does so in a - * seperate thread */ - class QueuedListener - implements XAccessibleEventListener, Runnable - { - public QueuedListener() - { - System.out.println ("starting new queued listener"); - - // initiate thread - new Thread(this, "QueuedListener").start(); - } - - /** The queue of event objects, LinkedList<Runnable> - * The queue object will also serve as lock for the - * consumer/producer type syncronization. - */ - protected LinkedList aQueue = new LinkedList(); - - /// This thread's main method: deliver all events - public void run() - { - // in an infinite loop, check for events to deliver, then - // wait on lock (which will be notified when new events arrive) - while( true ) - { - Runnable aEvent = null; - do - { - synchronized( aQueue ) - { - aEvent = (aQueue.size() > 0) ? - (Runnable)aQueue.removeFirst() : null; - } - if( aEvent != null ) - { - System.out.println("Deliver event: " + - aEvent.hashCode()); - try - { - aEvent.run(); - } - catch( Throwable e ) - { - System.out.println( - "Exception during event delivery: " + e ); - } - } - } - while( aEvent != null ); - - try - { - synchronized( aQueue ) - { - aQueue.wait(); - } - } - catch( Exception e ) - { - // can't wait? odd! - System.err.println("Can't wait!"); - } - } - } - - - public void disposing( final EventObject aEvent) - { - System.out.println( "Queue disposing: " + aEvent.hashCode() ); - synchronized( aQueue ) - { - aQueue.addLast( new Runnable() - { - public void run() - { - AccessibilityTreeModel.this.disposing( aEvent ); - } - public int hashCode() - { - return aEvent.hashCode(); - } - } ); - aQueue.notify(); - } - } - - public void notifyEvent( final AccessibleEventObject aEvent ) - { - System.out.println( "Queue notifyEvent: " + aEvent.hashCode() ); - synchronized( aQueue ) - { - aQueue.addLast( new Runnable() - { - public void run() - { - AccessibilityTreeModel.this.notifyEvent( aEvent ); - } - public int hashCode() - { - return aEvent.hashCode(); - } - } ); - aQueue.notify(); - } - } - } - + private EventListener maEventListener; } |