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 import javax.swing.*;
25 import java.awt.Dimension;
26 import java.awt.*;
27 import java.awt.geom.*;
28 
29 import com.sun.star.accessibility.XAccessible;
30 import com.sun.star.accessibility.XAccessibleContext;
31 import com.sun.star.accessibility.XAccessibleComponent;
32 
33 import com.sun.star.awt.Point;
34 import com.sun.star.awt.Size;
35 import com.sun.star.uno.UnoRuntime;
36 
37 
38 /** Display the currently focused accessible object graphically.
39 */
40 public class GraphicalDisplay
41     extends JPanel
42     implements IAccessibleObjectDisplay
43 {
44     /** Create a new graphical widget the displays some of the geometrical
45         information availbable from accessible objects.
46     */
GraphicalDisplay()47     public GraphicalDisplay ()
48     {
49         setPreferredSize (new Dimension (300,200));
50     }
51 
52 
53     /** Paint some or all of the area of this widget with the outlines of
54         the currently focues object and its ancestors.
55      */
paintComponent(Graphics g)56     public synchronized void paintComponent (Graphics g)
57     {
58         super.paintComponent (g);
59 
60         setupTransformation ();
61 
62         // Draw the screen representation to give a hint of the location of the
63         // accessible object on the screen.
64         Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
65         // Fill the screen rectangle.
66         g.setColor (new Color (250,240,230));
67         g.fillRect (
68             (int)(mnHOffset+0.5),
69             (int)(mnVOffset+0.5),
70             (int)(mnScale*aScreenSize.getWidth()),
71             (int)(mnScale*aScreenSize.getHeight()));
72         // Draw a frame around the screen rectangle to increase its visibility.
73         g.setColor (Color.BLACK);
74         g.drawRect (
75             (int)(mnHOffset+0.5),
76             (int)(mnVOffset+0.5),
77             (int)(mnScale*aScreenSize.getWidth()),
78             (int)(mnScale*aScreenSize.getHeight()));
79 
80         // Now do the actual display of the accessible object.
81         drawAccessibleObject (g, mxContext, Color.GREEN);
82     }
paintChildren(Graphics g)83     public synchronized void paintChildren (Graphics g)
84     {
85     }
paintBorder(Graphics g)86     public synchronized void paintBorder (Graphics g)
87     {
88     }
89 
90 
91 
92 
93     /** Draw a simple representation of the given accessible object in the
94         specified color.
95     */
drawAccessibleObject(Graphics g, XAccessibleContext xContext, Color aColor)96     public void drawAccessibleObject (Graphics g, XAccessibleContext xContext, Color aColor)
97     {
98         if (xContext != null)
99         {
100             // First draw our parent.
101             XAccessible xParent = xContext.getAccessibleParent();
102             if (xParent != null)
103                 drawAccessibleObject (g, xParent.getAccessibleContext(), Color.GRAY);
104 
105             // When the context supports the XAccessibleComponent interface
106             // then draw its outline.
107             XAccessibleComponent xComponent =
108                 (XAccessibleComponent)UnoRuntime.queryInterface(
109                     XAccessibleComponent.class, xContext);
110             if (xComponent != null)
111             {
112                 // Get size and location on screen and transform them to fit
113                 // everything inside this widget.
114                 Point aLocation = xComponent.getLocationOnScreen();
115                 Size aSize = xComponent.getSize();
116                 g.setColor (aColor);
117                 g.drawRect (
118                     (int)(mnHOffset + mnScale*aLocation.X+0.5),
119                     (int)(mnVOffset + mnScale*aLocation.Y+0.5),
120                     (int)(mnScale*aSize.Width),
121                     (int)(mnScale*aSize.Height));
122             }
123         }
124     }
125 
126 
setAccessibleObject(XAccessibleContext xContext)127     public synchronized void setAccessibleObject (XAccessibleContext xContext)
128     {
129         mxContext = xContext;
130         repaint ();
131     }
132 
updateAccessibleObject(XAccessibleContext xContext)133     public synchronized void updateAccessibleObject (XAccessibleContext xContext)
134     {
135         repaint ();
136     }
137 
138 
139     /** Set up the transformation so that the graphical display can show a
140         centered representation of the whole screen.
141     */
setupTransformation()142     private void setupTransformation ()
143     {
144         Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
145         Dimension aWidgetSize = getSize();
146         if ((aScreenSize.getWidth() > 0) && (aScreenSize.getHeight() > 0))
147         {
148             // Calculate the scales that would map the screen onto the
149             // widget in both of the coordinate axes and select the smaller
150             // of the two: it maps the screen onto the widget in both axes
151             // at the same time.
152             double nHScale = (aWidgetSize.getWidth() - 10) / aScreenSize.getWidth();
153             double nVScale = (aWidgetSize.getHeight() - 10) / aScreenSize.getHeight();
154             if (nHScale < nVScale)
155                 mnScale = nHScale;
156             else
157                 mnScale = nVScale;
158 
159             // Calculate offsets that center the scaled screen inside the widget.
160             mnHOffset = (aWidgetSize.getWidth() - mnScale*aScreenSize.getWidth()) / 2.0;
161             mnVOffset = (aWidgetSize.getHeight() - mnScale*aScreenSize.getHeight()) / 2.0;
162         }
163         else
164         {
165             // In case of a degenerate (not yet initialized?) screen size
166             // use some meaningless default values.
167             mnScale = 1;
168             mnHOffset = 0;
169             mnVOffset = 0;
170         }
171     }
172 
173 
174     private XAccessibleContext mxContext;
175     private double mnScale;
176     private double mnHOffset;
177     private double mnVOffset;
178 }
179