/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import java.awt.geom.Rectangle2D;
import com.sun.star.accessibility.XAccessible;
import com.sun.star.accessibility.XAccessibleContext;
import com.sun.star.accessibility.XAccessibleComponent;
/** This canvas displays accessible objects graphically. Each accessible
object with graphical representation is represented by an
CanvasShape object and has to be added by the
The canvas listens to selection events of the associated JTree and highlights the first selected node of that tree.
*/ class Canvas extends JPanel implements MouseListener, MouseMotionListener, TreeSelectionListener//, Scrollable { // This constant can be passed to SetZoomMode to always show the whole screen. public static final int WHOLE_SCREEN = -1; public Canvas () { super (true); maObjects = new java.util.HashMap (); maNodes = new Vector (); maObjectList = new Vector (); maContexts = new Vector (); addMouseListener (this); addMouseMotionListener (this); maBoundingBox = new Rectangle (0,0,100,100); maTree = null; mnHOffset = 0; mnVOffset = 0; mnScale = 1; setShowText(false); setShowDescriptions (true); setShowNames (true); setAntialiasing (true); maLastWidgetSize = new Dimension (0,0); } /** Tell the canvas which tree view to use to highlight accessible objects. */ public void setTree (JTree aTree) { if (maTree != null) maTree.removeTreeSelectionListener (this); maTree = aTree; if (maTree != null) maTree.addTreeSelectionListener (this); } public void addNode (AccTreeNode aNode) { if (maNodes.indexOf (aNode) == -1) { maNodes.add (aNode); CanvasShape aObject = (CanvasShape) maObjects.get (aNode); if (aObject == null) { aObject = new CanvasShape (aNode); // Update bounding box that includes all objects. if (maObjects.size() == 0) maBoundingBox = aObject.getBBox(); else maBoundingBox = maBoundingBox.union (aObject.getBBox()); maObjects.put (aNode, aObject); maObjectList.add (aObject); } repaint (); } } public void removeNode (AccTreeNode aNode) { int i = maNodes.indexOf (aNode); if( i != -1 ) { Object aObject = maObjects.get(aNode); maObjectList.remove (aObject); maObjects.remove (aObject); maNodes.remove (aNode); repaint (); } } public void updateNode (AccTreeNode aNode) { int i = maNodes.indexOf (aNode); if (i != -1) { CanvasShape aObject = (CanvasShape)maObjects.get(aNode); if (aObject != null) aObject.update(); } } public void updateNodeGeometry (AccTreeNode aNode) { CanvasShape aObject = (CanvasShape)maObjects.get(aNode); if (aObject != null) aObject.updateGeometry(); } public void clear () { while (maNodes.size() > 0) removeNode ((AccTreeNode)maNodes.elementAt(0)); maNodes.clear(); maObjects.clear(); maObjectList.clear(); } public boolean getShowDescriptions () { return Options.GetBoolean ("ShowDescriptions"); } public void setShowDescriptions (boolean bNewValue) { Options.SetBoolean ("ShowDescriptions", bNewValue); repaint (); } public boolean getShowNames () { return Options.GetBoolean ("ShowNames"); } public void setShowNames (boolean bNewValue) { Options.SetBoolean ("ShowNames", bNewValue); repaint (); } public boolean getAntialiasing () { return Options.GetBoolean ("Antialiasing"); } public void setAntialiasing (boolean bNewValue) { Options.SetBoolean ("Antialiasing", bNewValue); repaint (); } public boolean getShowText () { return Options.GetBoolean ("ShowText"); } public void setShowText (boolean bNewValue) { Options.SetBoolean ("ShowText", bNewValue); repaint (); } public void setZoomMode (int nZoomMode) { Options.SetInteger ("ZoomMode", nZoomMode); repaint (); } public int getZoomMode () { return Options.GetInteger ("ZoomMode", WHOLE_SCREEN); } public void paintComponent (Graphics g) { synchronized (g) { super.paintComponent (g); Graphics2D g2 = (Graphics2D)g; if (getAntialiasing()) g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); else g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); setupTransformation (); // Draw the screen representation to give a hint of the location of the // accessible object on the screen. Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize(); Rectangle2D.Double aScreen = new Rectangle2D.Double ( mnHOffset, mnVOffset, mnScale*aScreenSize.getWidth(), mnScale*aScreenSize.getHeight()); // Fill the screen rectangle and draw a frame around it to increase its visibility. g2.setColor (new Color (250,240,230)); g2.fill (aScreen); g2.setColor (Color.BLACK); g2.draw (aScreen); synchronized (maObjectList) { int nCount = maObjectList.size(); boolean bShowDescriptions = getShowDescriptions(); boolean bShowNames = getShowNames(); boolean bShowText = getShowText(); for (int i=0; i