1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package org.openoffice.accessibility.awb;
25 
26 import java.awt.Cursor;
27 import java.awt.GridBagConstraints;
28 import java.awt.event.ActionEvent;
29 import java.awt.event.ActionListener;
30 import java.awt.event.WindowAdapter;
31 import java.awt.event.WindowEvent;
32 import javax.swing.ButtonGroup;
33 import javax.swing.JButton;
34 import javax.swing.JCheckBoxMenuItem;
35 import javax.swing.JComponent;
36 import javax.swing.JFrame;
37 import javax.swing.JMenu;
38 import javax.swing.JMenuBar;
39 import javax.swing.JMenuItem;
40 import javax.swing.JPanel;
41 import javax.swing.JRadioButtonMenuItem;
42 import javax.swing.JScrollPane;
43 import javax.swing.JSplitPane;
44 import javax.swing.event.TreeSelectionListener;
45 import javax.swing.event.TreeSelectionEvent;
46 import javax.swing.event.TreeExpansionListener;
47 import javax.swing.event.TreeWillExpandListener;
48 import javax.swing.tree.TreeNode;
49 import javax.swing.tree.TreePath;
50 
51 import com.sun.star.accessibility.XAccessible;
52 import com.sun.star.awt.XExtendedToolkit;
53 import com.sun.star.frame.XFrame;
54 import com.sun.star.frame.XTerminateListener;
55 import com.sun.star.lang.EventObject;
56 import com.sun.star.uno.UnoRuntime;
57 
58 import org.openoffice.accessibility.misc.MessageArea;
59 import org.openoffice.accessibility.misc.Options;
60 import org.openoffice.accessibility.misc.OfficeConnection;
61 import org.openoffice.accessibility.misc.SimpleOffice;
62 import org.openoffice.accessibility.awb.canvas.Canvas;
63 import org.openoffice.accessibility.awb.tree.AccessibilityTree;
64 import org.openoffice.accessibility.awb.tree.AccessibilityModel;
65 import org.openoffice.accessibility.awb.tree.DynamicAccessibilityModel;
66 import org.openoffice.accessibility.awb.view.ObjectViewContainer;
67 import org.openoffice.accessibility.awb.view.ObjectViewContainerWindow;
68 
69 
70 
71 /** This class manages the GUI of the work bench.
72     @see AccessibilityTreeModel
73         for the implementation of the tree view on the left side which also
74         manages the registration of accessibility listeners.
75     @see Canvas
76         for the graphical view of the accessible objects.
77 */
78 public class AccessibilityWorkBench
79             extends JFrame
80             implements XTerminateListener,
81                        ActionListener,
82                        TreeSelectionListener
83 {
84     public static final String msVersion = "v1.9";
85     public String msOptionsFileName = ".AWBrc";
86 
main(String args[])87     public static void main (String args[])
88     {
89         String sPipeName = System.getenv( "USER" );
90 
91         for (int i=0; i<args.length; i++)
92         {
93             if (args[i].equals ("-h") || args[i].equals ("--help") || args[i].equals ("-?"))
94             {
95                 System.out.println ("usage: AccessibilityWorkBench <option>*");
96                 System.out.println ("options:");
97                 System.out.println (" -p <pipe-name>    name of the pipe to use to connect to OpenOffice.org.");
98                 System.out.println ("                   Defaults to $USER.");
99                 System.exit (0);
100             }
101             else if (args[i].equals ("-p"))
102             {
103                 sPipeName = args[++i];
104             }
105         }
106 
107         saWorkBench = new AccessibilityWorkBench (sPipeName);
108     }
109 
110 
111 
112 
113     /** Return the one instance of the AccessibilityWorkBench
114         @return
115             Returns null when the AccessibilityWorkBench could not be
116             created successfully.
117     */
Instance()118     public static AccessibilityWorkBench Instance ()
119     {
120         return saWorkBench;
121     }
122 
123 
124 
125     /** Create an accessibility work bench that listens at the specified
126         port to Office applications.
127     */
AccessibilityWorkBench(String sPipeName)128     private AccessibilityWorkBench (String sPipeName)
129     {
130         mbInitialized = false;
131 
132         OfficeConnection.SetPipeName (sPipeName);
133         Options.Instance().Load (msOptionsFileName);
134         Layout ();
135 
136         MessageArea.println (System.getProperty ("os.name") + " / "
137             + System.getProperty ("os.arch") + " / "
138             + System.getProperty ("os.version"));
139         MessageArea.println ("Using pipe name " + sPipeName);
140 
141         maTree.addTreeSelectionListener (this);
142 
143         addWindowListener (new WindowAdapter ()
144             { public void windowClosing (WindowEvent e) {Quit();} }
145             );
146 
147         OfficeConnection.Instance().AddConnectionListener (this);
148         Initialize ();
149     }
150 
151 
152 
153 
154     /** Create and arrange the widgets of the GUI.
155     */
Layout()156     public void Layout ()
157     {
158         setSize (new java.awt.Dimension (800,600));
159 
160         JScrollPane aScrollPane;
161         GridBagConstraints constraints;
162 
163         // Create new layout.
164         java.awt.GridBagLayout aLayout = new java.awt.GridBagLayout ();
165         getContentPane().setLayout (aLayout);
166 
167         //  Accessible Tree.
168         javax.swing.tree.TreeModel treeModel = new DynamicAccessibilityModel();
169         maTree = new AccessibilityTree(treeModel);
170         // Add the model as tree listeners to be able to populate/clear the
171         // child lists on demand.
172         maTree.addTreeExpansionListener((TreeExpansionListener) treeModel);
173         maTree.addTreeWillExpandListener((TreeWillExpandListener) treeModel);
174 
175         JScrollPane aTreeScrollPane = new JScrollPane(
176             maTree,
177             JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
178             JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
179         aTreeScrollPane.setPreferredSize (new java.awt.Dimension (400,300));
180 
181         // Object view shows details about the currently selected accessible
182         // object.
183         maObjectViewContainer = new ObjectViewContainer ();
184         JScrollPane aObjectViewContainerScrollPane = new JScrollPane(
185             maObjectViewContainer,
186             JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
187             JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
188         aObjectViewContainerScrollPane.setPreferredSize (
189             new java.awt.Dimension (400,300));
190         JButton aCornerButton = new JButton ("CreateNewViewWindow");
191         aCornerButton.addActionListener (this);
192         aObjectViewContainerScrollPane.setCorner (
193             JScrollPane.LOWER_RIGHT_CORNER,
194             aCornerButton);
195 
196         // Split pane for tree view and object view.
197         JSplitPane aLeftViewSplitPane = new JSplitPane (
198             JSplitPane.VERTICAL_SPLIT,
199             aTreeScrollPane,
200             aObjectViewContainerScrollPane
201             );
202         aLeftViewSplitPane.setDividerLocation (300);
203         aLeftViewSplitPane.setContinuousLayout (true);
204 
205         //  Canvas.
206         maCanvas = new Canvas ();
207         maCanvas.SetTree (maTree);
208         JScrollPane aScrolledCanvas = new JScrollPane(maCanvas,
209             JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
210             JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
211         aScrolledCanvas.getViewport().setBackground (java.awt.Color.RED);
212         aScrolledCanvas.setPreferredSize (new java.awt.Dimension(600,400));
213 
214         // Split pane for tree view and canvas.
215         JSplitPane aViewSplitPane = new JSplitPane (
216             JSplitPane.HORIZONTAL_SPLIT,
217             aLeftViewSplitPane,
218             aScrolledCanvas
219             );
220         aViewSplitPane.setOneTouchExpandable(true);
221         aViewSplitPane.setDividerLocation (400);
222         aViewSplitPane.setContinuousLayout (true);
223 
224         // Split pane for the three views at the top and the message area.
225         MessageArea.Instance().setPreferredSize (new java.awt.Dimension(600,50));
226         JSplitPane aSplitPane = new JSplitPane (
227             JSplitPane.VERTICAL_SPLIT,
228             aViewSplitPane,
229             MessageArea.Instance());
230         aSplitPane.setOneTouchExpandable(true);
231         aSplitPane.setContinuousLayout (true);
232         addGridElement (aSplitPane, 0,0, 2,1, 3,3,
233             GridBagConstraints.CENTER, GridBagConstraints.BOTH);
234 
235         // Button bar.
236         maButtonBar = new javax.swing.JPanel();
237         java.awt.GridBagLayout aButtonLayout = new java.awt.GridBagLayout ();
238         maButtonBar.setLayout (new java.awt.FlowLayout());
239         addGridElement (maButtonBar, 0,3, 2,1, 1,0,
240             GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL);
241 
242         //  Buttons.
243         //        maConnectButton = createButton ("Connect", "connect");
244         //        maUpdateButton = createButton ("Update", "update");
245         //        maShapesButton = createButton ("Expand Shapes", "shapes");
246         maExpandButton = createButton ("Expand All", "expand");
247         maQuitButton = createButton ("Quit", "quit");
248         UpdateButtonStates ();
249 
250         setJMenuBar (CreateMenuBar ());
251 
252         setTitle("Accessibility Workbench " + msVersion);
253 
254         setVisible (true);
255         pack ();
256         aSplitPane.setDividerLocation (1.0);
257         validate ();
258         repaint();
259     }
260 
261 
262 
263 
264     /** Shortcut method for adding an object to a GridBagLayout.
265     */
addGridElement(JComponent object, int x, int y, int width, int height, int weightx, int weighty, int anchor, int fill)266     void addGridElement (JComponent object,
267         int x, int y,
268         int width, int height,
269         int weightx, int weighty,
270         int anchor, int fill)
271     {
272         GridBagConstraints constraints = new GridBagConstraints ();
273         constraints.gridx = x;
274         constraints.gridy = y;
275         constraints.gridwidth = width;
276         constraints.gridheight = height;
277         constraints.weightx = weightx;
278         constraints.weighty = weighty;
279         constraints.anchor = anchor;
280         constraints.fill = fill;
281         getContentPane().add (object, constraints);
282     }
283 
284 
285 
286 
287     /** Create a new button and place at the right most position into the
288         button bar.
289     */
createButton(String title, String command)290     public JButton createButton (String title, String command)
291     {
292         JButton aButton = new JButton (title);
293         aButton.setEnabled (false);
294         aButton.setActionCommand (command);
295         aButton.addActionListener (this);
296 
297         maButtonBar.add (aButton);
298         return aButton;
299     }
300 
301 
302 
303 
304     /** Create a menu bar for the application.
305         @return
306             Returns the new menu bar.  The returned reference is also
307             remembered in the data member <member>maMenuBar</member>.
308     */
CreateMenuBar()309     javax.swing.JMenuBar CreateMenuBar()
310     {
311         // Menu bar.
312         maMenuBar = new JMenuBar ();
313 
314         // File menu.
315         JMenu aFileMenu = new JMenu ("File");
316         maMenuBar.add (aFileMenu);
317         JMenuItem aItem;
318         aItem = new JMenuItem ("Quit");
319         aFileMenu.add (aItem);
320         aItem.addActionListener (this);
321 
322         // View menu.
323         JMenu aViewMenu = new JMenu ("View");
324         maMenuBar.add (aViewMenu);
325         ButtonGroup aGroup = new ButtonGroup ();
326         int nZoomMode = Options.GetInteger ("ZoomMode", Canvas.WHOLE_SCREEN);
327         JRadioButtonMenuItem aRadioButton = new JRadioButtonMenuItem (
328             "Whole Screen", nZoomMode==Canvas.WHOLE_SCREEN);
329         aGroup.add (aRadioButton);
330         aViewMenu.add (aRadioButton);
331         aRadioButton.addActionListener (this);
332         aRadioButton = new JRadioButtonMenuItem ("200%", nZoomMode==200);
333         aGroup.add (aRadioButton);
334         aViewMenu.add (aRadioButton);
335         aRadioButton.addActionListener (this);
336         aRadioButton = new JRadioButtonMenuItem ("100%", nZoomMode==100);
337         aGroup.add (aRadioButton);
338         aViewMenu.add (aRadioButton);
339         aRadioButton.addActionListener (this);
340         aRadioButton = new JRadioButtonMenuItem ("50%", nZoomMode==50);
341         aGroup.add (aRadioButton);
342         aViewMenu.add (aRadioButton);
343         aRadioButton.addActionListener (this);
344         aRadioButton = new JRadioButtonMenuItem ("25%", nZoomMode==25);
345         aGroup.add (aRadioButton);
346         aViewMenu.add (aRadioButton);
347         aRadioButton.addActionListener (this);
348         aRadioButton = new JRadioButtonMenuItem ("10%", nZoomMode==10);
349         aGroup.add (aRadioButton);
350         aViewMenu.add (aRadioButton);
351         aRadioButton.addActionListener (this);
352 
353         // Options menu.
354         JMenu aOptionsMenu = new JMenu ("Options");
355         maMenuBar.add (aOptionsMenu);
356         JCheckBoxMenuItem aCBItem;
357         aCBItem = new JCheckBoxMenuItem ("Show Descriptions",
358                                          Options.GetBoolean("ShowDescriptions"));
359         aOptionsMenu.add (aCBItem);
360         aCBItem.addActionListener (this);
361 
362         aCBItem = new JCheckBoxMenuItem ("Show Names",
363                                          Options.GetBoolean ("ShowNames"));
364         aOptionsMenu.add (aCBItem);
365         aCBItem.addActionListener (this);
366 
367         aCBItem = new JCheckBoxMenuItem ("Show Text",
368                                          Options.GetBoolean ("ShowText"));
369         aOptionsMenu.add (aCBItem);
370         aCBItem.addActionListener (this);
371 
372         aCBItem = new JCheckBoxMenuItem ("Antialiased Rendering",
373                                          Options.GetBoolean ("Antialiasing"));
374         aOptionsMenu.add (aCBItem);
375         aCBItem.addActionListener (this);
376 
377         // Help menu.
378         JMenu aHelpMenu = new JMenu ("Help");
379         maMenuBar.add (aHelpMenu);
380 
381         aItem = new JMenuItem ("Help");
382         aHelpMenu.add (aItem);
383         aItem.addActionListener (this);
384 
385         aItem = new JMenuItem ("News");
386         aHelpMenu.add (aItem);
387         aItem.addActionListener (this);
388 
389         aItem = new JMenuItem ("About");
390         aHelpMenu.add (aItem);
391         aItem.addActionListener (this);
392 
393         return maMenuBar;
394     }
395 
396 
397 
398 
399     /** Initialize the AWB.  This includes clearing the canvas, add
400         listeners, creation of a new tree model for the tree list box and
401         the update of the button states.
402 
403         This method may be called any number of times.  Note that all
404         actions will be carried out every time.  The main purpose of a
405         second call is that of a re-initialization after a reconnect.
406     */
Initialize()407     protected void Initialize ()
408     {
409         maCanvas.SetTree (maTree);
410 
411         SimpleOffice aOffice = SimpleOffice.Instance ();
412         if (aOffice != null)
413         {
414             // Add terminate listener.
415             if (aOffice.GetDesktop() != null)
416                 aOffice.GetDesktop().addTerminateListener (this);
417 
418         }
419 
420         mbInitialized = true;
421         UpdateButtonStates ();
422     }
423 
424 
425 
426 
427     /** Update the states of the buttons according to the internal state of
428         the AWB.
429     */
UpdateButtonStates()430     protected void UpdateButtonStates ()
431     {
432         //        maConnectButton.setEnabled (mbInitialized);
433         maQuitButton.setEnabled (true);
434         //        maUpdateButton.setEnabled (mbInitialized);
435         maExpandButton.setEnabled (mbInitialized);
436         //        maShapesButton.setEnabled (mbInitialized);
437     }
438 
439 
440 
441     /** Callback for GUI actions from the buttons.
442     */
actionPerformed(ActionEvent aEvent)443     public void actionPerformed (ActionEvent aEvent)
444     {
445         String sCommand = aEvent.getActionCommand();
446         if (sCommand.equals("connect"))
447         {
448             SimpleOffice.Clear();
449             Initialize ();
450         }
451         else if (sCommand.equals("quit"))
452         {
453             Quit ();
454         }
455         else if (sCommand.equals("update"))
456         {
457 //			maTree.Dispose();
458             Initialize ();
459         }
460         else if (sCommand.equals("shapes"))
461         {
462             Cursor aCursor = getCursor();
463             setCursor (new Cursor (Cursor.WAIT_CURSOR));
464             //            maTree.expandShapes();
465             setCursor (aCursor);
466         }
467         else if (sCommand.equals("expand"))
468         {
469             Cursor aCursor = getCursor();
470             setCursor (new Cursor (Cursor.WAIT_CURSOR));
471 
472             for (int i=0; i<maTree.getRowCount(); i++)
473                 maTree.expandRow (i);
474             //            maAccessibilityTree.expandAll();
475             setCursor (aCursor);
476         }
477         else if (sCommand.equals ("Quit"))
478         {
479             System.out.println ("exiting");
480             System.exit (0);
481         }
482         else if (sCommand.equals ("Show Descriptions"))
483         {
484             Options.SetBoolean ("ShowDescriptions",
485                 ((JCheckBoxMenuItem)aEvent.getSource()).getState());
486             maCanvas.repaint();
487         }
488         else if (sCommand.equals ("Show Names"))
489         {
490             Options.SetBoolean ("ShowNames",
491                 ((JCheckBoxMenuItem)aEvent.getSource()).getState());
492             maCanvas.repaint();
493         }
494         else if (sCommand.equals ("Show Text"))
495         {
496             Options.SetBoolean ("ShowText",
497                 ((JCheckBoxMenuItem)aEvent.getSource()).getState());
498             maCanvas.repaint();
499         }
500         else if (sCommand.equals ("Antialiased Rendering"))
501         {
502             Options.SetBoolean ("Antialiasing",
503                 ((JCheckBoxMenuItem)aEvent.getSource()).getState());
504             maCanvas.repaint();
505         }
506         else if (sCommand.equals ("Help"))
507         {
508             HelpWindow.Instance().loadFile ("help.html");
509         }
510         else if (sCommand.equals ("News"))
511         {
512             try{
513                 HelpWindow.Instance().loadFile ("news.html");
514             } catch (Exception ex) {}
515         }
516         else if (sCommand.equals ("About"))
517         {
518             HelpWindow.Instance().loadFile ("about.html");
519         }
520         else if (sCommand.equals ("Whole Screen"))
521         {
522             Options.SetInteger ("ZoomMode", Canvas.WHOLE_SCREEN);
523             maCanvas.repaint();
524         }
525         else if (sCommand.equals ("200%"))
526         {
527             Options.SetInteger ("ZoomMode", 200);
528             maCanvas.repaint();
529         }
530         else if (sCommand.equals ("100%"))
531         {
532             Options.SetInteger ("ZoomMode", 100);
533             maCanvas.repaint();
534         }
535         else if (sCommand.equals ("50%"))
536         {
537             Options.SetInteger ("ZoomMode", 50);
538             maCanvas.repaint();
539         }
540         else if (sCommand.equals ("25%"))
541         {
542             Options.SetInteger ("ZoomMode", 25);
543             maCanvas.repaint();
544         }
545         else if (sCommand.equals ("10%"))
546         {
547             Options.SetInteger ("ZoomMode", 10);
548             maCanvas.repaint();
549         }
550         else if (sCommand.equals ("<connected>"))
551         {
552             Connected ();
553         }
554         else if (sCommand.equals ("CreateNewViewWindow"))
555         {
556             TreePath aSelectionPath = maTree.getSelectionPath();
557             if (aSelectionPath != null)
558             {
559                 javax.swing.tree.TreeNode aSelectedNode =
560                     (javax.swing.tree.TreeNode)aSelectionPath.getLastPathComponent();
561                 if (aSelectedNode instanceof XAccessible) {
562                    new ObjectViewContainerWindow (((XAccessible) aSelectedNode).getAccessibleContext());
563                 }
564             }
565         }
566         else
567         {
568             System.err.println("unknown command " + sCommand);
569         }
570     }
571 
572 
573 
574 
575     /** TreeSelectionListener
576 		Tell the object view and the canvas about the selected object.
577 	*/
valueChanged(TreeSelectionEvent aEvent)578     public void valueChanged (TreeSelectionEvent aEvent) {
579 
580         if (aEvent.isAddedPath()) {
581             Cursor aCursor = getCursor();
582             setCursor (new Cursor (Cursor.WAIT_CURSOR));
583 
584             javax.swing.tree.TreePath aPath = aEvent.getPath();
585             maTree.scrollPathToVisible (aPath);
586             Object aObject = aPath.getLastPathComponent();
587             implSetCurrentObject( aObject );
588             if (aObject instanceof XAccessible)
589             {
590                 if (maObjectViewContainer != null)
591                     maObjectViewContainer.SetObject( ((XAccessible)aObject).getAccessibleContext() );
592             }
593             if (maCanvas != null)
594                 maCanvas.SelectObject ((TreeNode) aObject);
595             setCursor (aCursor);
596         } else {
597             implSetCurrentObject( aEvent.getPath().getLastPathComponent() );
598             if (maObjectViewContainer != null)
599                 maObjectViewContainer.SetObject (null);
600             if (maCanvas != null)
601                 maCanvas.SelectObject (null);
602         }
603     }
604 
605 
implSetCurrentObject( Object i_object )606     private void implSetCurrentObject( Object i_object )
607     {
608         if ( maObjectViewContainer == null )
609             return;
610         if ( maCurrentObject != null )
611         {
612             AccessibilityModel.removeEventListener( (TreeNode)maCurrentObject, maObjectViewContainer );
613         }
614         maCurrentObject = i_object;
615         if ( maCurrentObject != null )
616         {
617             AccessibilityModel.addEventListener( (TreeNode)maCurrentObject, maObjectViewContainer );
618         }
619     }
620 
621     // XEventListener
disposing(EventObject aSourceObj)622     public void disposing (EventObject aSourceObj)
623     {
624 		XFrame xFrame = (XFrame)UnoRuntime.queryInterface(
625 		    XFrame.class, aSourceObj.Source);
626 
627 		if( xFrame != null )
628 			System.out.println("frame disposed");
629 		else
630 			System.out.println("controller disposed");
631     }
632 
633 
634 
635 
636 	// XTerminateListener
queryTermination(final EventObject aEvent)637 	public void queryTermination(final EventObject aEvent) throws com.sun.star.frame.TerminationVetoException
638 	{
639 		System.out.println ("Terminate Event : " + aEvent);
640 	}
641 
642 
643 
644 
645 	// XTerminateListener
notifyTermination(final EventObject aEvent)646 	public void notifyTermination(final EventObject aEvent)
647 	{
648 		System.out.println ("Notifiy Termination Event : " + aEvent);
649 	}
650 
651 
652     /** Called after the AWB is connected to an Office application.
653     */
Connected()654     private void Connected ()
655     {
656         // Clear the tree and by expanding the root node initiate the
657         // scanning and insertion of nodes for the top-level windows.
658 //        maTree.Clear();
659 //        maTree.collapseRow (0);
660 //        maTree.expandRow (0);
661 
662         // Register the top window listener.
663         XExtendedToolkit xToolkit =
664             SimpleOffice.Instance().GetExtendedToolkit();
665         if (xToolkit != null)
666         {
667             maTree.setToolkit(xToolkit);
668         }
669     }
670 
671 
672     /** Called when shutting down the AWB tool.
673     */
Quit()674     private void Quit ()
675     {
676 //        maTree.Dispose();
677         System.exit (0);
678     }
679 
680     /// The Singleton Workbench object.
681     private static AccessibilityWorkBench
682         saWorkBench = null;
683 
684     private JPanel maMainPanel;
685     private JPanel maButtonBar;
686     private Canvas maCanvas;
687     private AccessibilityTree maTree;
688     private ObjectViewContainer maObjectViewContainer;
689     private JButton
690         maConnectButton,
691         maQuitButton,
692         maUpdateButton,
693         maExpandButton,
694         maShapesButton;
695     private JMenuBar maMenuBar;
696     private boolean mbInitialized;
697     private Object maCurrentObject = null;
698 }
699