2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 import java
.awt
.Cursor
;
20 import java
.awt
.event
.ActionEvent
;
21 import java
.awt
.event
.MouseAdapter
;
22 import java
.awt
.event
.MouseEvent
;
23 import java
.util
.ArrayList
;
25 import javax
.swing
.AbstractAction
;
26 import javax
.swing
.JPopupMenu
;
27 import javax
.swing
.JTree
;
28 import javax
.swing
.event
.TreeExpansionEvent
;
29 import javax
.swing
.event
.TreeExpansionListener
;
30 import javax
.swing
.event
.TreeWillExpandListener
;
31 import javax
.swing
.tree
.TreePath
;
33 import com
.sun
.star
.accessibility
.XAccessibleContext
;
37 /** This is the tree component that is responsible for displaying the
38 contents of the tree model on the screen.
40 public class AccessibilityTree
41 implements TreeExpansionListener
, TreeWillExpandListener
43 /** Create a new accessibility tree. Use the specified message display
44 for displaying messages and the specified canvas to draw the
45 graphical representations of accessible objects on.
47 public AccessibilityTree ()
49 maTree
= new JTree ();
51 AccessibilityTreeModel aModel
=
52 new AccessibilityTreeModel (
53 new StringNode ("Please press Update button", null));
54 maTree
.setModel (aModel
);
56 maTree
.addMouseListener (new MouseListener (this));
58 // Listen to expansions and collapses to change the mouse cursor.
60 maTree
.addTreeWillExpandListener (this);
61 maTree
.addTreeExpansionListener (this);
64 public JTree
getComponent ()
69 // Change cursor during expansions to show the user that this is a
71 public void treeWillExpand (TreeExpansionEvent e
)
73 if (mnExpandLevel
== 0)
75 maTree
.setCursor (new Cursor (Cursor
.WAIT_CURSOR
));
79 public void treeWillCollapse (TreeExpansionEvent e
)
81 if (mnExpandLevel
== 0)
83 maTree
.setCursor (new Cursor (Cursor
.WAIT_CURSOR
));
87 public void treeExpanded (TreeExpansionEvent e
)
90 if (mnExpandLevel
== 0)
92 maTree
.setCursor (new Cursor (Cursor
.DEFAULT_CURSOR
));
95 public void treeCollapsed (TreeExpansionEvent e
)
98 if (mnExpandLevel
== 0)
100 maTree
.setCursor (new Cursor (Cursor
.DEFAULT_CURSOR
));
106 public void SetCanvas (Canvas aCanvas
)
108 ((AccessibilityTreeModel
)maTree
.getModel()).setCanvas(aCanvas
);
111 /** Expand the nodes in the subtree rooted in aNode according to the
112 specified expander. The tree is locked during the expansion.
114 private void expandTree (AccessibleTreeNode aNode
, Expander aExpander
)
116 if (mnExpandLevel
== 0)
118 maTree
.setEnabled (false);
122 ((AccessibilityTreeModel
)maTree
.getModel()).lock ();
126 expandTree (new TreePath (aNode
.createPath()), aExpander
);
134 if (mnExpandLevel
== 0)
136 maTree
.setEnabled (true);
137 ((AccessibilityTreeModel
)maTree
.getModel()).unlock (aNode
);
141 private TreePath
expandTree( TreePath aPath
, Expander aExpander
)
143 // return first expanded object
144 TreePath aFirst
= null;
149 Object aObj
= aPath
.getLastPathComponent();
151 // expand this object, if the Expander tells us so
152 if( aExpander
.expand( aObj
) )
154 maTree
.expandPath (aPath
);
158 // visit all children
159 if (aObj
instanceof AccessibleTreeNode
)
161 AccessibleTreeNode aNode
= (AccessibleTreeNode
)aObj
;
162 int nLength
= aNode
.getChildCount();
163 for( int i
= 0; i
< nLength
; i
++ )
165 TreePath aRet
= expandTree(
166 aPath
.pathByAddingChild( aNode
.getChild( i
) ),
175 System
.out
.println ("caught exception while expanding tree path "
177 e
.printStackTrace ();
184 /** Expand all nodes and their subtrees that represent shapes. Call
185 * this method from the outside. */
186 public void expandShapes ()
188 expandShapes ((AccessibleTreeNode
)maTree
.getModel().getRoot());
190 private void expandShapes (AccessibleTreeNode aNode
)
192 expandTree (aNode
, new ShapeExpander());
195 /** Expand all nodes */
196 public void expandAll ()
198 expandAll ((AccessibleTreeNode
)maTree
.getModel().getRoot());
200 private void expandAll (AccessibleTreeNode aNode
)
202 expandTree (aNode
, new AllExpander());
208 public Dimension getPreferredSize ()
210 Dimension aPreferredSize = super.getPreferredSize();
211 Dimension aMinimumSize = super.getMinimumSize();
212 if (aPreferredSize.width < aMinimumSize.width)
213 aPreferredSize.width = aMinimumSize.width;
214 return aPreferredSize;
218 private class MouseListener
extends MouseAdapter
220 public MouseListener (AccessibilityTree aTree
)
225 public void mousePressed(MouseEvent e
) { popupTrigger(e
); }
227 public void mouseClicked(MouseEvent e
) { popupTrigger(e
); }
229 public void mouseEntered(MouseEvent e
) { popupTrigger(e
); }
231 public void mouseExited(MouseEvent e
) { popupTrigger(e
); }
233 public void mouseReleased(MouseEvent e
) { popupTrigger(e
); }
235 private boolean popupTrigger( MouseEvent e
)
237 boolean bIsPopup
= e
.isPopupTrigger();
241 int selRow
= maTree
.getComponent().getRowForLocation(e
.getX(), e
.getY());
245 TreePath aPath
= maTree
.getComponent().getPathForLocation(e
.getX(), e
.getY());
248 Object aObject
= aPath
.getLastPathComponent();
249 JPopupMenu aMenu
= new JPopupMenu();
250 if( aObject
instanceof AccTreeNode
)
252 AccTreeNode aNode
= (AccTreeNode
)aObject
;
254 ArrayList
<String
> aActions
= new ArrayList
<String
>();
255 aMenu
.add (new AccessibilityTree
.ShapeExpandAction(maTree
, aNode
));
256 aMenu
.add (new AccessibilityTree
.SubtreeExpandAction(maTree
, aNode
));
258 aNode
.getActions(aActions
);
259 for( int i
= 0; i
< aActions
.size(); i
++ )
261 aMenu
.add( new NodeAction(
266 else if (aObject
instanceof AccessibleTreeNode
)
268 AccessibleTreeNode aNode
= (AccessibleTreeNode
)aObject
;
269 String
[] aActionNames
= aNode
.getActions();
270 int nCount
=aActionNames
.length
;
273 for (int i
=0; i
<nCount
; i
++)
274 aMenu
.add( new NodeAction(
283 aMenu
.show (maTree
.getComponent(),
289 private final AccessibilityTree maTree
;
292 private class NodeAction
extends AbstractAction
294 private final int mnIndex
;
295 private final AccessibleTreeNode maNode
;
297 private NodeAction( String aName
, AccessibleTreeNode aNode
, int nIndex
)
304 public void actionPerformed(ActionEvent e
)
306 maNode
.performAction(mnIndex
);
310 // This action expands all shapes in the subtree rooted in the specified node.
311 private class ShapeExpandAction
extends AbstractAction
313 private final AccessibilityTree maTree
;
314 private final AccTreeNode maNode
;
315 public ShapeExpandAction (AccessibilityTree aTree
, AccTreeNode aNode
)
317 super ("Expand Shapes");
321 public void actionPerformed (ActionEvent e
)
323 maTree
.expandShapes (maNode
);
327 // This action expands all nodes in the subtree rooted in the specified node.
328 private class SubtreeExpandAction
extends AbstractAction
330 private final AccessibilityTree maTree
;
331 private final AccTreeNode maNode
;
332 public SubtreeExpandAction (AccessibilityTree aTree
, AccTreeNode aNode
)
334 super ("Expand Subtree");
338 public void actionPerformed (ActionEvent e
)
340 maTree
.expandAll (maNode
);
344 /** Predicate class to determine whether a node should be expanded
345 * For use with expandTree method */
346 private abstract class Expander
348 abstract public boolean expand (Object aObject
);
351 /** expand all nodes */
352 private class AllExpander
extends Expander
355 public boolean expand(Object aObject
) { return true; }
358 /** expand all nodes with accessibility roles > 100 */
359 private class ShapeExpander
extends Expander
362 public boolean expand (Object aObject
)
364 if (aObject
instanceof AccTreeNode
)
366 AccTreeNode aNode
= (AccTreeNode
)aObject
;
367 XAccessibleContext xContext
= aNode
.getContext();
368 if (xContext
!= null && xContext
.getAccessibleRole() >= 100)
377 private final JTree maTree
;
378 private int mnExpandLevel
;