Java Access Bridge
通过 Java 访问桥 API,您可以给使用Java应用程序编写的在windows系统上运行的图形化系统
开发辅助技术应用程序
。它包含本机方法,使您能够查看和操作有关 Java 应用程序中 GUI 元素的信息,这些信息将通过 Java 访问桥转发到辅助技术应用程序。
运行逻辑如图所示:
官方文档:
https://docs.oracle.com/javase/accessbridge/2.0.2/toc.htm
其他网址:
Java Accessibility API 规范
: http://download.oracle.com/javase/6/docs/api/javax/accessibility/package-summary.html
Java Accessibility 索引页
: http://download.oracle.com/javase/6/docs/technotes/guides/access/index.html
Swing API 官网: http://download.oracle.com/javase/6/docs/technotes/guides/swing/index.html
笔记
1. 安装
- 我发现我电脑中的JDK1.8, JDK11, JDK17都已经存在JAB相关的文件, 无需手动安装
- 经官网查询 , Java 访问桥已集成到 Java SE 7 及更高版本中。因此,对于 Java SE 6 及更早版本,我们需要手动集成
1.1 手动安装说明
我们首先从下载地址, 下载Java Access Bridge 2.0.2
并按照以下表格进行复制操作即可.
以下安装说明看不懂或者您电脑是32位, 请自行查阅 安装 Java 访问桥
以下表格中出现的%JAVAHOME64%
或者%JAVAHOME32%
表示的目录类似于:
- JDK:
C:\Program Files\Java\jdk1.6.0_24\jre
- JRE:
C:\Program Files\Java\jre6
怎样知道JDK是32位还是64位?
在要使用的jdk的bin目录下用命令
java -version
查看, 如果没有出现64 bit
字样, 说明该jdk是32位的, 否则是64位的
Java访问桥文件 | 目标目录 |
---|---|
WindowsAccessBridge-32.dll | %WINDOWSHOME%\SYSWOW64 |
WindowsAccessBridge-64.dll | %WINDOWSHOME%\SYSTEM32 |
JavaAccessBridge-32.dll | %JAVAHOME32%\bin |
JavaAccessBridge-64.dll | %JAVAHOME64%\bin |
JAWTAccessBridge-32.dll | %JAVAHOME32%\bin |
JAWTAccessBridge-64.dll | %JAVAHOME64%\bin |
accessibility.properties | %JAVAHOME32%\lib 或者%JAVAHOME64%\lib |
access-bridge-32.jar | %JAVAHOME32%\lib\ext |
access-bridge-64.jar | %JAVAHOME64%\lib\ext |
jaccess.jar | %JAVAHOME32%\lib\ext 或者%JAVAHOME64%\lib\ext |
有关用法示例,请参阅示例:JavaFerret.cpp
1.2 JAB工作过程
- JVM加载java.awt.Toolkit时,默认执行initAssistiveTechnologies方法。该方法加载accessibility.properties文件。
- 读取文件中的assistive_technologies属性。
- 找到access-bridge-32.jar下的com.sun.java.accessibility.AccessBridge并加载。
- loadAssistiveTechnologies方法加载JavaAccessBridge-32.dll。
- 该dll启动隐藏窗口,并调用com.sun.java.accessibility.AccessBridge.java中的方法。
- 应用程序调用WindowsAccessBridge-32.dll,使用SendMessage(WM_COPYDATA)方法与 JavaAccessBridge-32.dll隐藏窗口进行通讯。
2. Java Ferret介绍
Java 雪貂示例使用 Java 辅助功能实用程序 API 来检查有关 Java 虚拟机中对象的可访问信息。它使您能够选择不同的方法来选择要检查的对象:
- 当发生任意数量的事件时,例如焦点更改、鼠标移动、属性更改、菜单选择以及显示弹出菜单
- 当指针位于对象上时,或当鼠标悬停在窗口上时
一旦选择了一个对象进行检查,Java 雪貂就会显示对该对象调用 Java 辅助功能 API 方法的结果。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SSAKk1vD-1673503496113)(D:\应用\文档\入职时文件\typora文件\开发相关\学习\技术学习\image-20221008100534334-1665194735898-1.png)]
对应按钮介绍请看JAVA Ferret示例 (oracle.com)
3. Java Monkey介绍
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sB5O4IID-1673503496113)(D:\应用\文档\入职时文件\typora文件\开发相关\学习\技术学习\image-20221008102238633-1665195759720-3.png)]
JAVA Monkey示例 (oracle.com)
-
像猴子一样,Java猴子在特定Java虚拟机中的组件树中“摆动”,并在树视图中显示层次结构。此外,如果用户在树中选择一个节点,然后从“Panels”菜单中选择“Accessibility API Panel”,Java Monkey 将向用户显示一个窗口,其中显示该对象的辅助功能信息。
-
从**“File**”菜单中选择“Refresh Tree”菜单。Java Monkey 构建一个属于 Java 应用程序和小程序的顶级窗口列表,然后递归查询这些窗口中的元素,构建所有 Java 应用程序中所有 GUI 组件和系统中运行的所有 JVM 中的小程序的树。
-
构建 GUI 树后,可以通过在树中选择单个 GUI 组件,然后选择“Panels”,然后选择“Display Accessibility Information”来查看有关该组件的详细辅助功能信息。
4. Java Access Bridge API
通过 Java 访问桥 API,您可以为使用 Java 应用程序的微软视窗操作系统开发辅助技术应用程序。它包含本机方法,使您能够查看和操作有关 Java 应用程序中 GUI 元素的信息,这些信息将通过 Java 访问桥转发到辅助技术应用程序。
4.1 接口文件
Java 访问桥 API 可以在三个文件中找到:AccessBridgeCalls.h
, AccessBridgePackages.h
和AccessBridgeCallbacks.h
。这些文件分别对应于 Java 访问桥 API 调用、API 数据结构和 API 回调。
4.2 接口调用
Java 访问桥 API 调用包含在AccessBridgeCalls.h
中,要使用它们,还必须编译文件 AccessBridgeCalls.c
,该文件充当应用程序与WindowsAccessBridge.dll
之间的接口。
4.3 初始化/关闭函数
BOOL initializeAccessBridge(); //启动 Java 访问桥。在调用此函数之前,不能使用 Java 访问桥 API 的任何部分。
BOOL shutdownAccessBridge(); //关闭 Java 访问桥。在应用程序使用完 Java 访问桥时(在应用程序存在之前),调用此函数非常重要,这样 Java 访问桥可以正确执行内存清理。
4.4 网关Gateway函数
通常在调用任何其他 Java 访问桥 API 函数之前调用这些函数:
BOOL IsJavaWindow(HWND window);//检查给定窗口是否实现了 Java 可访问性 API。
BOOL GetAccessibleContextFromHWND(HWND target, long *vmID, AccessibleContext *ac);//获取给定窗口的AccessibleContext和vmID值。许多 Java 访问桥函数都需要AccessibleContext和vmID值。
注: 虚拟机编号vmID 和根节点ac
4.6 事件处理函数
它们采用一个函数指针,该指针指向将处理事件类型的函数。当您不再对接收这些类型的事件感兴趣时,请再次调用该函数并传入值。在文件NULLAccessBridgeCallbacks.h
中查找需要传递到这些函数中的函数指针的原型。有关这些原型的详细信息,请参阅“API 回调”部分。
void SetFocusGained(AccessBridge_FocusGainedFP fp);
void SetFocusLost(AccessBridge_FocusLostFP fp);
4.7 general函数
为了确定可用的功能,您可以从调用中获取版本信息。
void ReleaseJavaObject(long vmID, Java_Object object);
//释放 Java 对象`object`使用的内存,其中object 是 Java 访问桥返回给您的对象。Java 访问桥会自动维护对它在 JVM 中返回给您的所有 Java 对象的引用,以便它们不会被垃圾回收。为了防止内存泄漏,您必须在完成 Java 访问桥返回给您的所有 Java 对象后调用ReleaseJavaObject。有关如何执行此操作的说明,请参阅JavaFerret.c
BOOL GetVersionInfo(long vmID, AccessBridgeVersionInfo *info);
//获取应用程序正在使用的 Java 访问桥实例的版本信息。您可以使用此信息来确定 Java 访问桥版本的可用功能。
注意:为了确定JVM的版本,您需要传入一个有效的vmID;否则,返回的只是应用程序WindowsAccessBridge.DLL连接到的文件的版本。
4.8 可访问的上下文函数
函数GetAccessibleContextAt和GetAccessableContextWithFocus检索Accessible Context对象,这是Accessibble对象和JVM cookie的神奇cookie(实际上是Java对象引用)。您可以使用这两个cookie通过Java Access Bridge引用对象。大多数Java Access Bridge API函数都要求您传入这两个参数。
函数GetAccessibleContextInfo返回关于属于JVM的AccessibbleContext对象的详细信息。为了提高性能,Java Accessibility API中的各种不同方法被收集到Java Access Bridge API中的几个例程中,并以结构值的形式返回。这些结构值在文件AccessBridgePackages.h和在“API回调”一节中介绍。
函数GetAccessibleChildFromContext和GetAccessableParentFromContex使您能够遍历GUI组件层次结构,检索特定GUI对象的第n个子级或父级。
BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent, jint x, jint y, AccessibleContext *ac);//检索窗口的对象或鼠标指针下的对象AccessibleContext。
BOOL GetAccessibleContextWithFocus(HWND window, long *vmID, AccessibleContext *ac);//检索窗口的对象或具有焦点的对象AccessibleContext。
BOOL GetAccessibleContextInfo(long vmID, AccessibleContext ac, AccessibleContextInfo *info);//从AccessibleContext对象ac检索AccessibleContextInfo对象。
AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index);//返回表示对象ac的第n个子对象的AccessibleContext对象,其中n由值index指定。
AccessibleContext GetAccessibleParentFromContext(long vmID, AccessibleContext ac);//返回表示对象ac的父级的AccessibleContext对象。
4.9 Accessible Text函数
这些函数获取Java Accessibility API提供的AccessibleText信息,为了提高效率,这些信息被分解为七个块。如果AccessibleContextInfo数据结构中的标志AccessibleText设置为TRUE,则AccessibbleContext中包含Accessible文本信息。这些函数中使用的结构值在文件AccessBridgePackages.h中定义并在“API回调”一节中介绍。
BOOL GetAccessibleTextInfo(long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y);
BOOL GetAccessibleTextItems(long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index);
BOOL GetAccessibleTextSelectionInfo(long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection);
char *GetAccessibleTextAttributes(long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes);
BOOL GetAccessibleTextRect(long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index);
BOOL GetAccessibleTextRange(long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len);
BOOL GetAccessibleTextLineBounds(long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex);
4.10 Accessible Value函数
这些函数获取Java Accessibility API提供的AccessibleValue信息。如果AccessibleContextInfo数据结构中的标志AccessibleValue设置为TRUE,则AccessibbleContext对象中包含Accessible Value信息。返回的值是字符串(char*value),因为无法预先判断该值是整数、浮点值还是Java语言构造Java.lang.Number子类的其他对象。
BOOL GetCurrentAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len);
BOOL GetMaximumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_ *value, short len);
BOOL GetMinimumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_ *value, short len);
4.11 Accessible Selection函数
这些函数获取并操作Java Accessibility API提供的AccessibleSelection信息。如果AccessibleContextInfo数据结构中的标志AccessibleSelection设置为TRUE,则AccessibbleContext中包含Accessible Selection信息。AccessibleSelection支持是第一个可以操作用户界面的地方,而不是通过添加和删除选择中的项目来进行查询。有些函数使用子坐标中的索引,而其他函数使用选择坐标。例如,通过传递子索引从选择中添加到移除(例如,将第四个子项添加到选择中)。另一方面,枚举所选子对象是在选择坐标中完成的(例如,获取所选第一个对象的AccessibleContext)。
void AddAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i);
void ClearAccessibleSelectionFromContext(long vmID, AccessibleSelection as);
jobject GetAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i);
int GetAccessibleSelectionCountFromContext(long vmID, AccessibleSelection as);
BOOL IsAccessibleChildSelectedFromContext(long vmID, AccessibleSelection as, int i);
void RemoveAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i);
void SelectAllAccessibleSelectionFromContext(long vmID, AccessibleSelection as);
4.12 接口数据结构
4.13 接口回调
4.14 AccessibilityContext 内容
AccessibilityContext 表示所有可访问对象返回的最少信息,并通过在实现辅助接口的对象上调用 getAccessibleContext
方法来获取。此信息包括对象的可访问名称、说明、角色和状态,以及有关对象的父项和子项的信息。此外,还包括 JavaBeans TM 属性更改支持,以允许辅助技术在可访问属性的值发生更改时进行学习。辅助上下文还包含用于获取有关组件的更具体辅助功能信息的方法。如果组件支持它,这些方法将返回一个实现以下一个或多个接口的对象:
- 辅助操作 - 对象可以执行一个或多个操作。此接口为辅助技术提供了标准机制,用于确定这些操作是什么并告诉对象执行这些操作。任何可以操作的对象都应返回一个对象,该对象在可访问上下文中调用
getAccessibleAction
方法时实现此接口。 - 可访问组件 - 对象具有图形表示。此接口为辅助技术提供了标准机制,用于确定和设置对象的图形表示形式。在屏幕上呈现的任何对象都应返回一个对象,当在可访问的上下文中调用
getAccessibleComponent
方法时,该对象应返回一个实现此接口的对象。 - 辅助选择 - 对象允许选择其子对象。此接口为辅助技术提供了标准机制,用于确定当前选定的儿童以及修改选择集。任何具有可选择子级的对象都应返回一个对象,该对象在“可访问”图标文本上调用
getAccesibleSelection
方法时实现此接口。 - 辅助文本 - 对象在显示屏上显示可编辑的文本信息。此接口为辅助技术提供了通过其内容、属性和空间位置访问该文本的标准机制。任何包含可编辑文本的对象都应返回一个对象,该对象在可访问上下文中调用
getAccessibleText
方法时实现此接口。 - 可访问的超文本 - 对象在显示屏上显示超文本信息。此接口为辅助技术提供了通过其内容、属性和空间位置访问该超文本的标准机制。任何包含超文本的对象都应返回一个对象,当在可访问的上下文中调用
getAccessibleText
方法时,该对象实现此接口。 - 可访问值 - 对象支持数值。此接口为辅助技术提供了标准机制,用于确定和设置对象的当前值以及最小值和最大值。任何支持数值的对象都应返回一个对象,该对象在可访问上下文中调用
getAccessibleValue
方法时实现此接口。
5. 用java语言写辅助系统
如果你想用java语言编写辅助系统, 那么只需要自己写一个jar包(你的辅助系统) , 并把该jar包的入口写到accessibility.properties文件中即可
操作步骤:
%JAVA_HOME%/jre/lib/ext
目录下放你编写的jar包- 打开
%JAVA_HOME%/jre/lib
下accessibility.properties
文件
此文件肯定会包含assistive_technologies
这一行数据 , 我们需要修改后面的全限类定名 改为我们自己的(也就是你复制到ext文件夹下的jar包的入口类全名), 比如:
assistive_technologies=com.alibaba.taobao.JavaAssistive
- 如果你系统用到
JAWTAccessBridge-32.dll
或者JAWTAccessBridge-32.dll
, 那么需要你在%JAVA_HOME%/jre/bin
文件夹下复制这两个文件, 请注意jdk的位数, 不要复制错了
效果:
任何用该jdk环境的java图形化系统启动前都会先加载你再properties文件里配置的类对象, 也就是说: “你咋这个类写的所有内容会在系统启动前执行”
应用:
- 对系统做自动化
- 写辅助阅读器(给盲人使用)
- 启动java图形化系统前的做的任何操作: 统计启动次数, 发送提醒消息等
6. 重要API网址
1. AccessibilityContext :
AccessibleContext
表示所有可访问对象返回的最小信息。 此信息包括对象的可访问名称,描述,角色和状态,以及有关其父级和子级的信息。
https://www.runoob.com/manual/jdk11api/java.desktop/javax/accessibility/AccessibleContext.html
2. javax.accessibility:
定义用户界面组件与提供对这些组件的访问的辅助技术之间的契约。
https://www.runoob.com/manual/jdk11api/java.desktop/javax/accessibility/package-summary.html
3. com.sun.java.accessibility.util:
提供组成Java Accessibility Utilities的接口和类的集合。 这些类由Assistive Technologies使用,例如盲人使用的屏幕阅读器,并帮助提供对实现Java Accessibility API的GUI工具包的访问。
https://www.runoob.com/manual/jdk11api/jdk.accessibility/com/sun/java/accessibility/util/package-summary.html
希望对你学习Java访问桥有所帮助