1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * The Contents of this file are made available subject to the terms of 4*cdf0e10cSrcweir * the BSD license. 5*cdf0e10cSrcweir * 6*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 7*cdf0e10cSrcweir * All rights reserved. 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * Redistribution and use in source and binary forms, with or without 10*cdf0e10cSrcweir * modification, are permitted provided that the following conditions 11*cdf0e10cSrcweir * are met: 12*cdf0e10cSrcweir * 1. Redistributions of source code must retain the above copyright 13*cdf0e10cSrcweir * notice, this list of conditions and the following disclaimer. 14*cdf0e10cSrcweir * 2. Redistributions in binary form must reproduce the above copyright 15*cdf0e10cSrcweir * notice, this list of conditions and the following disclaimer in the 16*cdf0e10cSrcweir * documentation and/or other materials provided with the distribution. 17*cdf0e10cSrcweir * 3. Neither the name of Sun Microsystems, Inc. nor the names of its 18*cdf0e10cSrcweir * contributors may be used to endorse or promote products derived 19*cdf0e10cSrcweir * from this software without specific prior written permission. 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22*cdf0e10cSrcweir * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23*cdf0e10cSrcweir * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24*cdf0e10cSrcweir * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25*cdf0e10cSrcweir * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26*cdf0e10cSrcweir * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27*cdf0e10cSrcweir * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 28*cdf0e10cSrcweir * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29*cdf0e10cSrcweir * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 30*cdf0e10cSrcweir * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 31*cdf0e10cSrcweir * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32*cdf0e10cSrcweir * 33*cdf0e10cSrcweir *************************************************************************/ 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir import javax.swing.*; 36*cdf0e10cSrcweir import java.awt.Dimension; 37*cdf0e10cSrcweir import java.awt.*; 38*cdf0e10cSrcweir import java.awt.geom.*; 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir import com.sun.star.accessibility.XAccessible; 41*cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleContext; 42*cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleComponent; 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir import com.sun.star.awt.Point; 45*cdf0e10cSrcweir import com.sun.star.awt.Size; 46*cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime; 47*cdf0e10cSrcweir 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir /** Display the currently focused accessible object graphically. 50*cdf0e10cSrcweir */ 51*cdf0e10cSrcweir public class GraphicalDisplay 52*cdf0e10cSrcweir extends JPanel 53*cdf0e10cSrcweir implements IAccessibleObjectDisplay 54*cdf0e10cSrcweir { 55*cdf0e10cSrcweir /** Create a new graphical widget the displays some of the geometrical 56*cdf0e10cSrcweir information availbable from accessible objects. 57*cdf0e10cSrcweir */ 58*cdf0e10cSrcweir public GraphicalDisplay () 59*cdf0e10cSrcweir { 60*cdf0e10cSrcweir setPreferredSize (new Dimension (300,200)); 61*cdf0e10cSrcweir } 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir /** Paint some or all of the area of this widget with the outlines of 65*cdf0e10cSrcweir the currently focues object and its ancestors. 66*cdf0e10cSrcweir */ 67*cdf0e10cSrcweir public synchronized void paintComponent (Graphics g) 68*cdf0e10cSrcweir { 69*cdf0e10cSrcweir super.paintComponent (g); 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir setupTransformation (); 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir // Draw the screen representation to give a hint of the location of the 74*cdf0e10cSrcweir // accessible object on the screen. 75*cdf0e10cSrcweir Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize(); 76*cdf0e10cSrcweir // Fill the screen rectangle. 77*cdf0e10cSrcweir g.setColor (new Color (250,240,230)); 78*cdf0e10cSrcweir g.fillRect ( 79*cdf0e10cSrcweir (int)(mnHOffset+0.5), 80*cdf0e10cSrcweir (int)(mnVOffset+0.5), 81*cdf0e10cSrcweir (int)(mnScale*aScreenSize.getWidth()), 82*cdf0e10cSrcweir (int)(mnScale*aScreenSize.getHeight())); 83*cdf0e10cSrcweir // Draw a frame arround the screen rectangle to increase its visibility. 84*cdf0e10cSrcweir g.setColor (Color.BLACK); 85*cdf0e10cSrcweir g.drawRect ( 86*cdf0e10cSrcweir (int)(mnHOffset+0.5), 87*cdf0e10cSrcweir (int)(mnVOffset+0.5), 88*cdf0e10cSrcweir (int)(mnScale*aScreenSize.getWidth()), 89*cdf0e10cSrcweir (int)(mnScale*aScreenSize.getHeight())); 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir // Now do the actual display of the accessible object. 92*cdf0e10cSrcweir drawAccessibleObject (g, mxContext, Color.GREEN); 93*cdf0e10cSrcweir } 94*cdf0e10cSrcweir public synchronized void paintChildren (Graphics g) 95*cdf0e10cSrcweir { 96*cdf0e10cSrcweir } 97*cdf0e10cSrcweir public synchronized void paintBorder (Graphics g) 98*cdf0e10cSrcweir { 99*cdf0e10cSrcweir } 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir /** Draw a simple representation of the given accessible object in the 105*cdf0e10cSrcweir specified color. 106*cdf0e10cSrcweir */ 107*cdf0e10cSrcweir public void drawAccessibleObject (Graphics g, XAccessibleContext xContext, Color aColor) 108*cdf0e10cSrcweir { 109*cdf0e10cSrcweir if (xContext != null) 110*cdf0e10cSrcweir { 111*cdf0e10cSrcweir // First draw our parent. 112*cdf0e10cSrcweir XAccessible xParent = xContext.getAccessibleParent(); 113*cdf0e10cSrcweir if (xParent != null) 114*cdf0e10cSrcweir drawAccessibleObject (g, xParent.getAccessibleContext(), Color.GRAY); 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir // When the context supports the XAccessibleComponent interface 117*cdf0e10cSrcweir // then draw its outline. 118*cdf0e10cSrcweir XAccessibleComponent xComponent = 119*cdf0e10cSrcweir (XAccessibleComponent)UnoRuntime.queryInterface( 120*cdf0e10cSrcweir XAccessibleComponent.class, xContext); 121*cdf0e10cSrcweir if (xComponent != null) 122*cdf0e10cSrcweir { 123*cdf0e10cSrcweir // Get size and location on screen and transform them to fit 124*cdf0e10cSrcweir // everything inside this widget. 125*cdf0e10cSrcweir Point aLocation = xComponent.getLocationOnScreen(); 126*cdf0e10cSrcweir Size aSize = xComponent.getSize(); 127*cdf0e10cSrcweir g.setColor (aColor); 128*cdf0e10cSrcweir g.drawRect ( 129*cdf0e10cSrcweir (int)(mnHOffset + mnScale*aLocation.X+0.5), 130*cdf0e10cSrcweir (int)(mnVOffset + mnScale*aLocation.Y+0.5), 131*cdf0e10cSrcweir (int)(mnScale*aSize.Width), 132*cdf0e10cSrcweir (int)(mnScale*aSize.Height)); 133*cdf0e10cSrcweir } 134*cdf0e10cSrcweir } 135*cdf0e10cSrcweir } 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir public synchronized void setAccessibleObject (XAccessibleContext xContext) 139*cdf0e10cSrcweir { 140*cdf0e10cSrcweir mxContext = xContext; 141*cdf0e10cSrcweir repaint (); 142*cdf0e10cSrcweir } 143*cdf0e10cSrcweir 144*cdf0e10cSrcweir public synchronized void updateAccessibleObject (XAccessibleContext xContext) 145*cdf0e10cSrcweir { 146*cdf0e10cSrcweir repaint (); 147*cdf0e10cSrcweir } 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir /** Set up the transformation so that the graphical display can show a 151*cdf0e10cSrcweir centered representation of the whole screen. 152*cdf0e10cSrcweir */ 153*cdf0e10cSrcweir private void setupTransformation () 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize(); 156*cdf0e10cSrcweir Dimension aWidgetSize = getSize(); 157*cdf0e10cSrcweir if ((aScreenSize.getWidth() > 0) && (aScreenSize.getHeight() > 0)) 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir // Calculate the scales that would map the screen onto the 160*cdf0e10cSrcweir // widget in both of the coordinate axes and select the smaller 161*cdf0e10cSrcweir // of the two: it maps the screen onto the widget in both axes 162*cdf0e10cSrcweir // at the same time. 163*cdf0e10cSrcweir double nHScale = (aWidgetSize.getWidth() - 10) / aScreenSize.getWidth(); 164*cdf0e10cSrcweir double nVScale = (aWidgetSize.getHeight() - 10) / aScreenSize.getHeight(); 165*cdf0e10cSrcweir if (nHScale < nVScale) 166*cdf0e10cSrcweir mnScale = nHScale; 167*cdf0e10cSrcweir else 168*cdf0e10cSrcweir mnScale = nVScale; 169*cdf0e10cSrcweir 170*cdf0e10cSrcweir // Calculate offsets that center the scaled screen inside the widget. 171*cdf0e10cSrcweir mnHOffset = (aWidgetSize.getWidth() - mnScale*aScreenSize.getWidth()) / 2.0; 172*cdf0e10cSrcweir mnVOffset = (aWidgetSize.getHeight() - mnScale*aScreenSize.getHeight()) / 2.0; 173*cdf0e10cSrcweir } 174*cdf0e10cSrcweir else 175*cdf0e10cSrcweir { 176*cdf0e10cSrcweir // In case of a degenerate (not yet initialized?) screen size 177*cdf0e10cSrcweir // use some meaningless default values. 178*cdf0e10cSrcweir mnScale = 1; 179*cdf0e10cSrcweir mnHOffset = 0; 180*cdf0e10cSrcweir mnVOffset = 0; 181*cdf0e10cSrcweir } 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir 185*cdf0e10cSrcweir private XAccessibleContext mxContext; 186*cdf0e10cSrcweir private double mnScale; 187*cdf0e10cSrcweir private double mnHOffset; 188*cdf0e10cSrcweir private double mnVOffset; 189*cdf0e10cSrcweir } 190