3 import java
.awt
.event
.*;
5 import javax
.swing
.tree
.*;
6 import javax
.swing
.event
.TreeSelectionListener
;
7 import javax
.swing
.event
.TreeSelectionEvent
;
8 import java
.awt
.geom
.Rectangle2D
;
10 import com
.sun
.star
.accessibility
.XAccessible
;
11 import com
.sun
.star
.accessibility
.XAccessibleContext
;
12 import com
.sun
.star
.accessibility
.XAccessibleComponent
;
14 /** This canvas displays accessible objects graphically. Each accessible
15 object with graphical representation is represented by an
16 CanvasShape object and has to be added by the
17 <member>addAccessible</member> member function.
19 <p>The canvas listens to selection events of the associated JTree and
20 highlights the first selected node of that tree.</p>
24 implements MouseListener
, MouseMotionListener
, TreeSelectionListener
//, Scrollable
26 // This constant can be passed to SetZoomMode to always show the whole screen.
27 public static final int WHOLE_SCREEN
= -1;
32 maObjects
= new java
.util
.HashMap ();
33 maNodes
= new Vector ();
34 maObjectList
= new Vector ();
35 maContexts
= new Vector ();
36 addMouseListener (this);
37 addMouseMotionListener (this);
38 maBoundingBox
= new Rectangle (0,0,100,100);
44 setShowDescriptions (true);
46 setAntialiasing (true);
47 maLastWidgetSize
= new Dimension (0,0);
50 /** Tell the canvas which tree view to use to highlight accessible
53 public void setTree (JTree aTree
)
56 maTree
.removeTreeSelectionListener (this);
59 maTree
.addTreeSelectionListener (this);
65 public void addNode (AccTreeNode aNode
)
67 if (maNodes
.indexOf (aNode
) == -1)
71 CanvasShape aObject
= (CanvasShape
) maObjects
.get (aNode
);
74 aObject
= new CanvasShape (aNode
);
75 // Update bounding box that includes all objects.
76 if (maObjects
.size() == 0)
77 maBoundingBox
= aObject
.getBBox();
79 maBoundingBox
= maBoundingBox
.union (aObject
.getBBox());
81 maObjects
.put (aNode
, aObject
);
82 maObjectList
.add (aObject
);
89 public void removeNode (AccTreeNode aNode
)
91 int i
= maNodes
.indexOf (aNode
);
94 Object aObject
= maObjects
.get(aNode
);
95 maObjectList
.remove (aObject
);
96 maObjects
.remove (aObject
);
97 maNodes
.remove (aNode
);
102 public void updateNode (AccTreeNode aNode
)
104 int i
= maNodes
.indexOf (aNode
);
107 CanvasShape aObject
= (CanvasShape
)maObjects
.get(aNode
);
113 public void updateNodeGeometry (AccTreeNode aNode
)
115 CanvasShape aObject
= (CanvasShape
)maObjects
.get(aNode
);
117 aObject
.updateGeometry();
122 while (maNodes
.size() > 0)
123 removeNode ((AccTreeNode
)maNodes
.elementAt(0));
127 maObjectList
.clear();
130 public boolean getShowDescriptions ()
132 return Options
.GetBoolean ("ShowDescriptions");
135 public void setShowDescriptions (boolean bNewValue
)
137 Options
.SetBoolean ("ShowDescriptions", bNewValue
);
141 public boolean getShowNames ()
143 return Options
.GetBoolean ("ShowNames");
146 public void setShowNames (boolean bNewValue
)
148 Options
.SetBoolean ("ShowNames", bNewValue
);
152 public boolean getAntialiasing ()
154 return Options
.GetBoolean ("Antialiasing");
157 public void setAntialiasing (boolean bNewValue
)
159 Options
.SetBoolean ("Antialiasing", bNewValue
);
163 public boolean getShowText ()
165 return Options
.GetBoolean ("ShowText");
168 public void setShowText (boolean bNewValue
)
170 Options
.SetBoolean ("ShowText", bNewValue
);
174 public void setZoomMode (int nZoomMode
)
176 Options
.SetInteger ("ZoomMode", nZoomMode
);
180 public int getZoomMode ()
182 return Options
.GetInteger ("ZoomMode", WHOLE_SCREEN
);
186 public void paintComponent (Graphics g
)
190 super.paintComponent (g
);
192 Graphics2D g2
= (Graphics2D
)g
;
193 if (getAntialiasing())
194 g2
.setRenderingHint (RenderingHints
.KEY_ANTIALIASING
,
195 RenderingHints
.VALUE_ANTIALIAS_ON
);
197 g2
.setRenderingHint (RenderingHints
.KEY_ANTIALIASING
,
198 RenderingHints
.VALUE_ANTIALIAS_OFF
);
200 setupTransformation ();
202 // Draw the screen representation to give a hint of the location of the
203 // accessible object on the screen.
204 Dimension aScreenSize
= Toolkit
.getDefaultToolkit().getScreenSize();
205 Rectangle2D
.Double aScreen
= new Rectangle2D
.Double (
208 mnScale
*aScreenSize
.getWidth(),
209 mnScale
*aScreenSize
.getHeight());
210 // Fill the screen rectangle and draw a frame arround it to increase its visibility.
211 g2
.setColor (new Color (250,240,230));
213 g2
.setColor (Color
.BLACK
);
216 synchronized (maObjectList
)
218 int nCount
= maObjectList
.size();
219 boolean bShowDescriptions
= getShowDescriptions();
220 boolean bShowNames
= getShowNames();
221 boolean bShowText
= getShowText();
222 for (int i
=0; i
<nCount
; i
++)
224 CanvasShape aCanvasShape
= (CanvasShape
)maObjectList
.elementAt(i
);
227 mnHOffset
, mnVOffset
, mnScale
,
228 bShowDescriptions
, bShowNames
, bShowText
);
232 // Paint highlighted frame around active object as the last thing.
233 if (maActiveObject
!= null)
234 maActiveObject
.paint_highlight (
236 mnHOffset
, mnVOffset
, mnScale
);
243 /** Set up the transformation so that the graphical display can show a
244 centered representation of the whole screen.
246 private void setupTransformation ()
248 // Turn off scrollbars when showing the whole screen. Otherwise show them when needed.
249 JViewport aViewport
= (JViewport
)getParent();
250 JScrollPane aScrollPane
= (JScrollPane
)aViewport
.getParent();
251 int nZoomMode
= getZoomMode();
252 if (nZoomMode
== WHOLE_SCREEN
)
254 if (aScrollPane
.getHorizontalScrollBarPolicy()
255 != JScrollPane
.HORIZONTAL_SCROLLBAR_NEVER
)
256 aScrollPane
.setHorizontalScrollBarPolicy (JScrollPane
.HORIZONTAL_SCROLLBAR_NEVER
);
257 if (aScrollPane
.getVerticalScrollBarPolicy()
258 != JScrollPane
.VERTICAL_SCROLLBAR_NEVER
)
259 aScrollPane
.setVerticalScrollBarPolicy (JScrollPane
.VERTICAL_SCROLLBAR_NEVER
);
263 if (aScrollPane
.getHorizontalScrollBarPolicy()
264 != JScrollPane
.HORIZONTAL_SCROLLBAR_AS_NEEDED
)
265 aScrollPane
.setHorizontalScrollBarPolicy (JScrollPane
.HORIZONTAL_SCROLLBAR_AS_NEEDED
);
266 if (aScrollPane
.getVerticalScrollBarPolicy()
267 != JScrollPane
.VERTICAL_SCROLLBAR_AS_NEEDED
)
268 aScrollPane
.setVerticalScrollBarPolicy (JScrollPane
.VERTICAL_SCROLLBAR_AS_NEEDED
);
271 Dimension aScreenSize
= Toolkit
.getDefaultToolkit().getScreenSize();
272 Dimension aWidgetSize
= aViewport
.getSize();
274 if ((aScreenSize
.getWidth() > 0) && (aScreenSize
.getHeight() > 0))
276 if (nZoomMode
== WHOLE_SCREEN
)
278 // Calculate the scales that would map the screen onto the
279 // widget in both of the coordinate axes and select the
281 // of the two: it maps the screen onto the widget in both
282 // axes at the same time.
283 double nHScale
= (aWidgetSize
.getWidth() - 10) / aScreenSize
.getWidth();
284 double nVScale
= (aWidgetSize
.getHeight() - 10) / aScreenSize
.getHeight();
285 if (nHScale
< nVScale
)
292 mnScale
= nZoomMode
/ 100.0;
295 // Calculate offsets that center the scaled screen inside the widget.
296 mnHOffset
= (aWidgetSize
.getWidth() - mnScale
*aScreenSize
.getWidth()) / 2.0;
297 mnVOffset
= (aWidgetSize
.getHeight() - mnScale
*aScreenSize
.getHeight()) / 2.0;
303 setPreferredSize (new Dimension (
304 (int)(2*mnHOffset
+ mnScale
* aScreenSize
.getWidth()),
305 (int)(2*mnVOffset
+ mnScale
* aScreenSize
.getHeight())));
310 // In case of a degenerate (not yet initialized?) screen size
311 // use some meaningless default values.
317 maLastWidgetSize
= aWidgetSize
;
322 /** Call getAccessibleAt to determine accessible object under mouse.
324 public void mouseClicked (MouseEvent e
)
328 public void mousePressed (MouseEvent e
)
330 CanvasShape aObjectUnderMouse
= FindCanvasShapeUnderMouse (e
);
331 highlightObject (aObjectUnderMouse
);
332 if ((e
.getModifiers() & InputEvent
.CTRL_MASK
) != 0)
334 maTree
.expandPath (aObjectUnderMouse
.getPath());
338 public void mouseReleased (MouseEvent e
)
342 public void mouseEntered (MouseEvent e
)
346 public void mouseExited (MouseEvent e
)
348 // Deselect currently active object.
349 if (maActiveObject
!= null)
351 maActiveObject
.unhighlight ();
352 maActiveObject
= null;
357 public void mouseDragged (MouseEvent e
)
361 public void mouseMoved (MouseEvent e
)
363 if ((e
.getModifiers() & InputEvent
.SHIFT_MASK
) != 0)
364 highlightObject (FindCanvasShapeUnderMouse (e
));
367 protected CanvasShape
FindCanvasShapeUnderMouse (MouseEvent e
)
369 int nObjects
= maObjects
.size();
370 CanvasShape aObjectUnderMouse
= null;
371 int nCount
= maObjectList
.size();
372 for (int i
=nCount
-1; i
>=0; --i
)
374 CanvasShape aObject
= (CanvasShape
)maObjectList
.elementAt(i
);
376 if (aObject
.contains (e
.getX(),e
.getY()))
378 aObjectUnderMouse
= aObject
;
382 return aObjectUnderMouse
;
385 protected boolean highlightObject (CanvasShape aNewActiveObject
)
387 if (aNewActiveObject
!= maActiveObject
)
389 if (maActiveObject
!= null)
390 maActiveObject
.unhighlight();
392 maActiveObject
= aNewActiveObject
;
393 if (maActiveObject
!= null)
397 maTree
.scrollPathToVisible (maActiveObject
.getPath());
398 maTree
.setSelectionPath (maActiveObject
.getPath());
401 maActiveObject
.highlight ();
410 /** Called when the selection of the tree changes. Highlight the
411 corresponding graphical representation of the first selected object.
413 public void valueChanged (javax
.swing
.event
.TreeSelectionEvent event
)
415 TreePath aPath
= event
.getPath();
416 Object aObject
= aPath
.getLastPathComponent();
417 if (aObject
instanceof AccTreeNode
)
419 CanvasShape aCanvasShape
= (CanvasShape
)maObjects
.get ((AccTreeNode
)aObject
);
420 if (highlightObject (aCanvasShape
))
435 private java
.util
.HashMap
445 // The size of the widget at the last call of setupTransformation()