1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski import java.awt.Color; 25*b1cdbd2cSJim Jagielski import java.awt.Font; 26*b1cdbd2cSJim Jagielski import java.awt.Dimension; 27*b1cdbd2cSJim Jagielski import javax.swing.JTextArea; 28*b1cdbd2cSJim Jagielski import javax.swing.JScrollPane; 29*b1cdbd2cSJim Jagielski import java.util.Vector; 30*b1cdbd2cSJim Jagielski 31*b1cdbd2cSJim Jagielski import com.sun.star.accessibility.XAccessible; 32*b1cdbd2cSJim Jagielski import com.sun.star.accessibility.XAccessibleContext; 33*b1cdbd2cSJim Jagielski import com.sun.star.accessibility.XAccessibleComponent; 34*b1cdbd2cSJim Jagielski import com.sun.star.accessibility.XAccessibleStateSet; 35*b1cdbd2cSJim Jagielski 36*b1cdbd2cSJim Jagielski import com.sun.star.uno.AnyConverter; 37*b1cdbd2cSJim Jagielski import com.sun.star.uno.UnoRuntime; 38*b1cdbd2cSJim Jagielski 39*b1cdbd2cSJim Jagielski import com.sun.star.awt.Point; 40*b1cdbd2cSJim Jagielski import com.sun.star.awt.Size; 41*b1cdbd2cSJim Jagielski 42*b1cdbd2cSJim Jagielski /** Display textual information for a given accessible object. This 43*b1cdbd2cSJim Jagielski includes the names of that object of its ancestors as well as some 44*b1cdbd2cSJim Jagielski information retrieved from the XAccessibleContext and 45*b1cdbd2cSJim Jagielski XAccessibleComponent interfaces. 46*b1cdbd2cSJim Jagielski */ 47*b1cdbd2cSJim Jagielski class TextualDisplay 48*b1cdbd2cSJim Jagielski extends JScrollPane 49*b1cdbd2cSJim Jagielski implements IAccessibleObjectDisplay 50*b1cdbd2cSJim Jagielski { 51*b1cdbd2cSJim Jagielski /** Create a new scroll pane that contains a text widget which display 52*b1cdbd2cSJim Jagielski information about given accessible objects. 53*b1cdbd2cSJim Jagielski */ TextualDisplay()54*b1cdbd2cSJim Jagielski public TextualDisplay () 55*b1cdbd2cSJim Jagielski { 56*b1cdbd2cSJim Jagielski // Create a text widget for displaying the text information... 57*b1cdbd2cSJim Jagielski maText = new JTextArea (80,10); 58*b1cdbd2cSJim Jagielski maText.setBackground (new Color (250,240,230)); 59*b1cdbd2cSJim Jagielski maText.setFont (new Font ("Courier", Font.PLAIN, 11)); 60*b1cdbd2cSJim Jagielski 61*b1cdbd2cSJim Jagielski // ...and set-up the scroll pane to show this widget. 62*b1cdbd2cSJim Jagielski setViewportView (maText); 63*b1cdbd2cSJim Jagielski setVerticalScrollBarPolicy (JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 64*b1cdbd2cSJim Jagielski setHorizontalScrollBarPolicy (JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); 65*b1cdbd2cSJim Jagielski } 66*b1cdbd2cSJim Jagielski 67*b1cdbd2cSJim Jagielski 68*b1cdbd2cSJim Jagielski 69*b1cdbd2cSJim Jagielski 70*b1cdbd2cSJim Jagielski /** Set the accessible object to display. Call this method e.g. when a 71*b1cdbd2cSJim Jagielski new object has been focused. 72*b1cdbd2cSJim Jagielski */ setAccessibleObject(XAccessibleContext xContext)73*b1cdbd2cSJim Jagielski public synchronized void setAccessibleObject (XAccessibleContext xContext) 74*b1cdbd2cSJim Jagielski { 75*b1cdbd2cSJim Jagielski // First clear the display area. 76*b1cdbd2cSJim Jagielski msTextContent = new String (); 77*b1cdbd2cSJim Jagielski 78*b1cdbd2cSJim Jagielski if (xContext != null) 79*b1cdbd2cSJim Jagielski { 80*b1cdbd2cSJim Jagielski String sIndentation = showParents (xContext); 81*b1cdbd2cSJim Jagielski showContextInfo (xContext, sIndentation); 82*b1cdbd2cSJim Jagielski showComponentInfo (xContext, sIndentation); 83*b1cdbd2cSJim Jagielski } 84*b1cdbd2cSJim Jagielski 85*b1cdbd2cSJim Jagielski maText.setText (msTextContent); 86*b1cdbd2cSJim Jagielski } 87*b1cdbd2cSJim Jagielski 88*b1cdbd2cSJim Jagielski 89*b1cdbd2cSJim Jagielski 90*b1cdbd2cSJim Jagielski updateAccessibleObject(XAccessibleContext xContext)91*b1cdbd2cSJim Jagielski public synchronized void updateAccessibleObject (XAccessibleContext xContext) 92*b1cdbd2cSJim Jagielski { 93*b1cdbd2cSJim Jagielski setAccessibleObject (xContext); 94*b1cdbd2cSJim Jagielski } 95*b1cdbd2cSJim Jagielski 96*b1cdbd2cSJim Jagielski 97*b1cdbd2cSJim Jagielski 98*b1cdbd2cSJim Jagielski /** Show some of the information available over the given object's 99*b1cdbd2cSJim Jagielski XAccessibleContext interface. 100*b1cdbd2cSJim Jagielski */ showContextInfo(XAccessibleContext xContext, String sIndentation)101*b1cdbd2cSJim Jagielski private void showContextInfo (XAccessibleContext xContext, String sIndentation) 102*b1cdbd2cSJim Jagielski { 103*b1cdbd2cSJim Jagielski // Show the description. 104*b1cdbd2cSJim Jagielski msTextContent += sIndentation + "Description: " 105*b1cdbd2cSJim Jagielski + xContext.getAccessibleDescription() + "\n"; 106*b1cdbd2cSJim Jagielski 107*b1cdbd2cSJim Jagielski showStates (xContext, sIndentation); 108*b1cdbd2cSJim Jagielski } 109*b1cdbd2cSJim Jagielski 110*b1cdbd2cSJim Jagielski 111*b1cdbd2cSJim Jagielski 112*b1cdbd2cSJim Jagielski 113*b1cdbd2cSJim Jagielski /** Show a list of all of the the given object's states. Use the 114*b1cdbd2cSJim Jagielski NameConverter class to transform the numerical state ids into human 115*b1cdbd2cSJim Jagielski readable names. 116*b1cdbd2cSJim Jagielski @param xContext 117*b1cdbd2cSJim Jagielski The accessible context for which to show the state names. 118*b1cdbd2cSJim Jagielski */ showStates(XAccessibleContext xContext, String sIndentation)119*b1cdbd2cSJim Jagielski private void showStates (XAccessibleContext xContext, String sIndentation) 120*b1cdbd2cSJim Jagielski { 121*b1cdbd2cSJim Jagielski // Get the state set object... 122*b1cdbd2cSJim Jagielski XAccessibleStateSet xStateSet = xContext.getAccessibleStateSet(); 123*b1cdbd2cSJim Jagielski // ...and retrieve an array of numerical ids. 124*b1cdbd2cSJim Jagielski short aStates[] = xStateSet.getStates(); 125*b1cdbd2cSJim Jagielski 126*b1cdbd2cSJim Jagielski // Iterate over the array and print the names of the states. 127*b1cdbd2cSJim Jagielski msTextContent += sIndentation + "States : "; 128*b1cdbd2cSJim Jagielski for (int i=0; i<aStates.length; i++) 129*b1cdbd2cSJim Jagielski { 130*b1cdbd2cSJim Jagielski if (i > 0) 131*b1cdbd2cSJim Jagielski msTextContent += ", "; 132*b1cdbd2cSJim Jagielski msTextContent += NameProvider.getStateName(aStates[i]); 133*b1cdbd2cSJim Jagielski } 134*b1cdbd2cSJim Jagielski msTextContent += "\n"; 135*b1cdbd2cSJim Jagielski } 136*b1cdbd2cSJim Jagielski 137*b1cdbd2cSJim Jagielski 138*b1cdbd2cSJim Jagielski 139*b1cdbd2cSJim Jagielski 140*b1cdbd2cSJim Jagielski /** When the given object supports the XAccessibleComponent interface then 141*b1cdbd2cSJim Jagielski show its size and location on the screen. 142*b1cdbd2cSJim Jagielski */ showComponentInfo(XAccessibleContext xContext, String sIndentation)143*b1cdbd2cSJim Jagielski private void showComponentInfo (XAccessibleContext xContext, String sIndentation) 144*b1cdbd2cSJim Jagielski { 145*b1cdbd2cSJim Jagielski // Try to cast the given accessible context to the 146*b1cdbd2cSJim Jagielski // XAccessibleComponent interface. 147*b1cdbd2cSJim Jagielski XAccessibleComponent xComponent = 148*b1cdbd2cSJim Jagielski (XAccessibleComponent)UnoRuntime.queryInterface( 149*b1cdbd2cSJim Jagielski XAccessibleComponent.class, xContext); 150*b1cdbd2cSJim Jagielski if (xComponent != null) 151*b1cdbd2cSJim Jagielski { 152*b1cdbd2cSJim Jagielski Point aLocation = xComponent.getLocationOnScreen(); 153*b1cdbd2cSJim Jagielski msTextContent += sIndentation + "Position : " 154*b1cdbd2cSJim Jagielski + aLocation.X + ", " + aLocation.Y + "\n"; 155*b1cdbd2cSJim Jagielski 156*b1cdbd2cSJim Jagielski Size aSize = xComponent.getSize(); 157*b1cdbd2cSJim Jagielski msTextContent += sIndentation + "Size : " 158*b1cdbd2cSJim Jagielski + aSize.Width + ", " + aSize.Height + "\n"; 159*b1cdbd2cSJim Jagielski } 160*b1cdbd2cSJim Jagielski } 161*b1cdbd2cSJim Jagielski 162*b1cdbd2cSJim Jagielski 163*b1cdbd2cSJim Jagielski 164*b1cdbd2cSJim Jagielski 165*b1cdbd2cSJim Jagielski 166*b1cdbd2cSJim Jagielski /** Print the names of the given object and its parents and return an 167*b1cdbd2cSJim Jagielski indentation string that can be used to print further information 168*b1cdbd2cSJim Jagielski about the object. 169*b1cdbd2cSJim Jagielski */ showParents(XAccessibleContext xContext)170*b1cdbd2cSJim Jagielski private String showParents (XAccessibleContext xContext) 171*b1cdbd2cSJim Jagielski { 172*b1cdbd2cSJim Jagielski // Create the path from the given object to its tree's root. 173*b1cdbd2cSJim Jagielski Vector aPathToRoot = new Vector(); 174*b1cdbd2cSJim Jagielski while (xContext != null) 175*b1cdbd2cSJim Jagielski { 176*b1cdbd2cSJim Jagielski aPathToRoot.add (xContext); 177*b1cdbd2cSJim Jagielski // Go up the hierarchy one level to the object's parent. 178*b1cdbd2cSJim Jagielski try 179*b1cdbd2cSJim Jagielski { 180*b1cdbd2cSJim Jagielski XAccessible xParent = xContext.getAccessibleParent(); 181*b1cdbd2cSJim Jagielski if (xParent != null) 182*b1cdbd2cSJim Jagielski xContext = xParent.getAccessibleContext(); 183*b1cdbd2cSJim Jagielski else 184*b1cdbd2cSJim Jagielski xContext = null; 185*b1cdbd2cSJim Jagielski } 186*b1cdbd2cSJim Jagielski catch (Exception e) 187*b1cdbd2cSJim Jagielski { 188*b1cdbd2cSJim Jagielski System.err.println ("caught exception " + e + " while getting path to root"); 189*b1cdbd2cSJim Jagielski } 190*b1cdbd2cSJim Jagielski } 191*b1cdbd2cSJim Jagielski 192*b1cdbd2cSJim Jagielski // Print the path in the accessibility tree from the given context to 193*b1cdbd2cSJim Jagielski // the root. 194*b1cdbd2cSJim Jagielski String sIndentation = new String (); 195*b1cdbd2cSJim Jagielski for (int i=aPathToRoot.size()-1; i>=0; i--) 196*b1cdbd2cSJim Jagielski { 197*b1cdbd2cSJim Jagielski XAccessibleContext xParentContext = (XAccessibleContext)aPathToRoot.get(i); 198*b1cdbd2cSJim Jagielski String sParentName = xParentContext.getAccessibleName(); 199*b1cdbd2cSJim Jagielski if (sParentName.length() == 0) 200*b1cdbd2cSJim Jagielski sParentName = "<unnamed> / Role " 201*b1cdbd2cSJim Jagielski + NameProvider.getRoleName(xParentContext.getAccessibleRole()); 202*b1cdbd2cSJim Jagielski msTextContent += sIndentation + sParentName + "\n"; 203*b1cdbd2cSJim Jagielski sIndentation += msIndentation; 204*b1cdbd2cSJim Jagielski } 205*b1cdbd2cSJim Jagielski 206*b1cdbd2cSJim Jagielski return sIndentation; 207*b1cdbd2cSJim Jagielski } 208*b1cdbd2cSJim Jagielski 209*b1cdbd2cSJim Jagielski 210*b1cdbd2cSJim Jagielski 211*b1cdbd2cSJim Jagielski /// The text widget that is used for the actual text display. 212*b1cdbd2cSJim Jagielski private JTextArea maText; 213*b1cdbd2cSJim Jagielski 214*b1cdbd2cSJim Jagielski /// The indentation with which an object's child is indented. 215*b1cdbd2cSJim Jagielski private final String msIndentation = new String(" "); 216*b1cdbd2cSJim Jagielski 217*b1cdbd2cSJim Jagielski /// The text content displayed by this object. 218*b1cdbd2cSJim Jagielski private String msTextContent = new String (); 219*b1cdbd2cSJim Jagielski } 220