alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (CAccessibleText.java)

This example Java source code file (CAccessibleText.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

accessible, accessiblecontext, accessibleeditabletext, accessibletext, awt, callable, component, element, exception, geometry, integer, jtextcomponent, point, rectangle2d, runnable, string, text, threading, threads

The CAccessibleText.java Java example source code

/*
 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.lwawt.macosx;

import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.util.concurrent.Callable;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleEditableText;
import javax.accessibility.AccessibleText;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;

class CAccessibleText {
    static AccessibleEditableText getAccessibleEditableText(final Accessible a, final Component c) {
        if (a == null) return null;

        return CAccessibility.invokeAndWait(new Callable<AccessibleEditableText>() {
            public AccessibleEditableText call() throws Exception {
                final AccessibleContext ac = a.getAccessibleContext();
                if (ac == null) return null;
                return ac.getAccessibleEditableText();
            }
        }, c);
    }

    static String getSelectedText(final Accessible a, final Component c) {
        if (a == null) return null;

        return CAccessibility.invokeAndWait(new Callable<String>() {
            public String call() throws Exception {
                final AccessibleContext ac = a.getAccessibleContext();
                if (ac == null) return null;

                final AccessibleText at = ac.getAccessibleText();
                if (at == null) return null;

                return at.getSelectedText();
            }
        }, c);
    }

    // replace the currently selected text with newText
    static void setSelectedText(final Accessible a, final Component c, final String newText) {
        if (a == null) return;

        CAccessibility.invokeLater(new Runnable() {
            public void run() {
                final AccessibleContext ac = a.getAccessibleContext();
                if (ac == null) return;

                final AccessibleEditableText aet = ac.getAccessibleEditableText();
                if (aet == null) return;

                final int selectionStart = aet.getSelectionStart();
                final int selectionEnd = aet.getSelectionEnd();
                aet.replaceText(selectionStart, selectionEnd, newText);
            }
        }, c);
    }

    static void setSelectedTextRange(final Accessible a, final Component c, final int startIndex, final int endIndex) {
        if (a == null) return;

        CAccessibility.invokeLater(new Runnable() {
            public void run() {
                final AccessibleContext ac = a.getAccessibleContext();
                if (ac == null) return;

                final AccessibleEditableText aet = ac.getAccessibleEditableText();
                if (aet == null) return;

                final boolean validRange = (startIndex >= 0) && (endIndex >= startIndex) && (endIndex <= aet.getCharCount());
                if (!validRange) return;

                aet.selectText(startIndex, endIndex);
            }
        }, c);
    }

    static String getTextRange(final AccessibleEditableText aet, final int start, final int stop, final Component c) {
        if (aet == null) return null;

        return CAccessibility.invokeAndWait(new Callable<String>() {
            public String call() throws Exception {
                return aet.getTextRange(start, stop);
            }
        }, c);
    }

    static int getCharacterIndexAtPosition(final Accessible a, final Component c, final int x, final int y) {
        if (a == null) return 0;

        return CAccessibility.invokeAndWait(new Callable<Integer>() {
            public Integer call() throws Exception {
                final AccessibleContext ac = a.getAccessibleContext();
                if (ac == null) return null;
                final AccessibleText at = ac.getAccessibleText();
                if (at == null) return null;
                // (x, y) passed in as java screen coords - (0, 0) at upper-left corner of screen.
                // Convert to java component-local coords
                final Point componentLocation = ac.getAccessibleComponent().getLocationOnScreen();
                final int localX = x - (int)componentLocation.getX();
                final int localY = y - (int)componentLocation.getY();

                return at.getIndexAtPoint(new Point(localX, localY));
            }
        }, c);
    }

    static int[] getSelectedTextRange(final Accessible a, final Component c) {
        if (a == null) return new int[2];

        return CAccessibility.invokeAndWait(new Callable<int[]>() {
            public int[] call() {
                final AccessibleContext ac = a.getAccessibleContext();
                if (ac == null) return new int[2];

                final AccessibleText at = ac.getAccessibleText();
                if (at == null) return new int[2];

                final int[] ret = new int[2];
                ret[0] = at.getSelectionStart();
                ret[1] = at.getSelectionEnd();
                return ret;
            }
        }, c);
    }


    static int[] getVisibleCharacterRange(final Accessible a, final Component c) {
        if (a == null) return null;
        return CAccessibility.invokeAndWait(new Callable<int[]>() {
            public int[] call() {
                return getVisibleCharacterRange(a);
            }
        }, c);
    }

    static int getLineNumberForIndex(final Accessible a, final Component c, final int index) {
        if (a == null) return 0;
        return CAccessibility.invokeAndWait(new Callable<Integer>() {
            public Integer call() {
                return Integer.valueOf(getLineNumberForIndex(a, index));
            }
        }, c);
    }

    static int getLineNumberForInsertionPoint(final Accessible a, final Component c) {
        if (a == null) return 0;
        return CAccessibility.invokeAndWait(new Callable<Integer>() {
            public Integer call() {
                return Integer.valueOf(getLineNumberForInsertionPoint(a));
            }
        }, c);
    }

    static int[] getRangeForLine(final Accessible a, final Component c, final int line) {
        if (a == null) return null;
        return CAccessibility.invokeAndWait(new Callable<int[]>() {
            public int[] call() {
                return getRangeForLine(a, line);
            }
        }, c);
    }

    static int[] getRangeForIndex(final Accessible a, final Component c, final int index) {
        if (a == null) return new int[2];

        return CAccessibility.invokeAndWait(new Callable<int[]>() {
            public int[] call() {
                final AccessibleContext ac = a.getAccessibleContext();
                if (ac == null) return new int[2];

                final AccessibleEditableText aet = ac.getAccessibleEditableText();
                if (aet == null) return new int[2];

                final int charCount = aet.getCharCount();
                if (index >= charCount) return new int[2];

                final String foundWord = aet.getAtIndex(AccessibleText.WORD, index);
                final int foundWordLength = foundWord.length();
                final String wholeString = aet.getTextRange(0, charCount - 1);

                // now we need to find the index of the foundWord in wholeString. It's somewhere pretty close to the passed-in index,
                // but we don't know if it's before or after the passed-in index. So, look behind and ahead of the passed-in index
                int foundWordIndex = -1;
                int offset = 0;
                while ((foundWordIndex == -1) && (offset < foundWordLength)) {
                    if (wholeString.regionMatches(true, index - offset, foundWord, 0, foundWordLength)) {
                        // is the index of foundWord to the left of the passed-in index?
                        foundWordIndex = index - offset;
                    }
                    if (wholeString.regionMatches(true, index + offset, foundWord, 0, foundWordLength)) {
                        // is the index of the foundWord to the right of the passed-in index?
                        foundWordIndex = index + offset;
                    }
                    offset++;
                }

                final int[] ret = new int[2];
                ret[0] = foundWordIndex;
                ret[1] = foundWordIndex + foundWordLength;
                return ret;
            }
        }, c);
    }

    // cmcnote: this method does not currently work for JLabels. JLabels, for some reason unbeknownst to me, do not
    // return a value from getAccessibleText. According to the javadocs, AccessibleJLabels implement AccessibleText,
    // so this doesn't really make sense. Perhaps a sun bug? Investigate. We currently get the text value out of labels
    // via "getAccessibleName". This just returns a String - so we don't know it's position, etc, as we do for
    // AccessibleText.
    static double[] getBoundsForRange(final Accessible a, final Component c, final int location, final int length) {
        final double[] ret = new double[4];
        if (a == null) return ret;

        return CAccessibility.invokeAndWait(new Callable<double[]>() {
            public double[] call() throws Exception {
                final AccessibleContext ac = a.getAccessibleContext();
                if (ac == null) return ret;

                final AccessibleText at = ac.getAccessibleText();
                if (at == null) {
                    ac.getAccessibleName();
                    ac.getAccessibleEditableText();
                    return ret;
                }

                final Rectangle2D boundsStart = at.getCharacterBounds(location);
                final Rectangle2D boundsEnd = at.getCharacterBounds(location + length - 1);
                if (boundsEnd == null || boundsStart == null) return ret;
                final Rectangle2D boundsUnion = boundsStart.createUnion(boundsEnd);
                if (boundsUnion.isEmpty()) return ret;

                final double localX = boundsUnion.getX();
                final double localY = boundsUnion.getY();

                final Point componentLocation = ac.getAccessibleComponent().getLocationOnScreen();
                final double screenX = componentLocation.getX() + localX;
                final double screenY = componentLocation.getY() + localY;

                ret[0] = screenX;
                ret[1] = screenY; // in java screen coords (from top-left corner of screen)
                ret[2] = boundsUnion.getWidth();
                ret[3] = boundsUnion.getHeight();
                return ret;
            }
        }, c);
    }

    static String getStringForRange(final Accessible a, final Component c, final int location, final int length) {
        if (a == null) return null;
        return CAccessibility.invokeAndWait(new Callable<String>() {
            public String call() throws Exception {
                final AccessibleContext ac = a.getAccessibleContext();
                if (ac == null) return null;

                final AccessibleEditableText aet = ac.getAccessibleEditableText();
                if (aet == null) return null;

                return aet.getTextRange(location, location + length);
            }
        }, c);
    }

    static int[] getVisibleCharacterRange(final Accessible a) {
        final Accessible sa = CAccessible.getSwingAccessible(a);
        if (!(sa instanceof JTextComponent)) return null;

        final JTextComponent jc = (JTextComponent) sa;
        final Rectangle rect = jc.getVisibleRect();
        final Point topLeft = new Point(rect.x, rect.y);
        final Point topRight = new Point(rect.x + rect.width, rect.y);
        final Point bottomLeft = new Point(rect.x, rect.y + rect.height);
        final Point bottomRight = new Point(rect.x + rect.width, rect.y + rect.height);

        int start = Math.min(jc.viewToModel(topLeft), jc.viewToModel(topRight));
        int end = Math.max(jc.viewToModel(bottomLeft), jc.viewToModel(bottomRight));
        if (start < 0) start = 0;
        if (end < 0) end = 0;
        return new int[] { start, end };
    }

    static int getLineNumberForIndex(final Accessible a, int index) {
        final Accessible sa = CAccessible.getSwingAccessible(a);
        if (!(sa instanceof JTextComponent)) return -1;

        final JTextComponent jc = (JTextComponent) sa;
        final Element root = jc.getDocument().getDefaultRootElement();

        // treat -1 special, returns the current caret position
        if (index == -1) index = jc.getCaretPosition();

        // Determine line number (can be -1)
        return root.getElementIndex(index);
    }

    static int getLineNumberForInsertionPoint(final Accessible a) {
        return getLineNumberForIndex(a, -1); // uses special -1 for above
    }

    static int[] getRangeForLine(final Accessible a, final int lineIndex) {
        Accessible sa = CAccessible.getSwingAccessible(a);
        if (!(sa instanceof JTextComponent)) return null;

        final JTextComponent jc = (JTextComponent) sa;
        final Element root = jc.getDocument().getDefaultRootElement();
        final Element line = root.getElement(lineIndex);
        if (line == null) return null;

        return new int[] { line.getStartOffset(), line.getEndOffset() };
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java CAccessibleText.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.