javax.accessibility 包是 Java Accessibility API 的核心部分,它提供了使 Java 应用程序更易于残障人士使用的框架。这个 API 允许辅助技术(如屏幕阅读器、语音识别软件等)与 Java 应用程序进行交互。
1、Accessible 接口 - 标识可访问的组件
2、AccessibleContext 类 - 提供可访问对象的上下文信息
3、AccessibleComponent 接口 - 处理组件的可视属性
4、AccessibleAction 接口 - 处理可执行操作
5、AccessibleText 接口 - 处理文本内容
import javax.accessibility.*;
import javax.swing.*;
import java.awt.*;
public class AccessibilityExample {
public static void main(String[] args) {
// 创建主窗口
JFrame frame = new JFrame("Accessibility Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
// 创建按钮并设置可访问性属性
JButton button = new JButton("Click Me");
setupButtonAccessibility(button);
// 创建文本框并设置可访问性属性
JTextField textField = new JTextField(15);
setupTextFieldAccessibility(textField);
// 创建标签并设置可访问性属性
JLabel label = new JLabel("Sample Label");
setupLabelAccessibility(label);
frame.add(button);
frame.add(textField);
frame.add(label);
frame.pack();
frame.setVisible(true);
}
private static void setupButtonAccessibility(JButton button) {
// 获取 AccessibleContext
AccessibleContext context = button.getAccessibleContext();
// 设置可访问的名称和描述
context.setAccessibleName("Action Button");
context.setAccessibleDescription("This button performs an action when clicked");
// 添加属性变化监听器
context.addPropertyChangeListener(evt -> {
System.out.println("Property changed: " + evt.getPropertyName());
});
}
private static void setupTextFieldAccessibility(JTextField textField) {
AccessibleContext context = textField.getAccessibleContext();
context.setAccessibleName("Input Field");
context.setAccessibleDescription("Enter text in this field");
// 检查是否支持 AccessibleText 接口
if (context instanceof AccessibleText) {
System.out.println("TextField supports AccessibleText interface");
}
}
private static void setupLabelAccessibility(JLabel label) {
AccessibleContext context = label.getAccessibleContext();
context.setAccessibleName("Information Label");
context.setAccessibleDescription("This label displays information");
}
}import javax.accessibility.*;
import javax.swing.*;
import java.awt.*;
public class CustomAccessibleComponent extends JPanel implements Accessible {
private String displayText = "Custom Component";
public CustomAccessibleComponent() {
setPreferredSize(new Dimension(200, 100));
setBackground(Color.LIGHT_GRAY);
// 设置可访问性上下文
getAccessibleContext().setAccessibleName("Custom Accessible Component");
getAccessibleContext().setAccessibleDescription("A custom component with accessibility support");
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawString(displayText, 20, 50);
}
@Override
public AccessibleContext getAccessibleContext() {
return new CustomAccessibleContext();
}
// 自定义 AccessibleContext 实现
private class CustomAccessibleContext extends AccessibleContext {
@Override
public String getAccessibleName() {
return "Custom Accessible Component";
}
@Override
public String getAccessibleDescription() {
return "This is a custom component with full accessibility support";
}
@Override
public AccessibleRole getAccessibleRole() {
return AccessibleRole.PANEL;
}
@Override
public AccessibleStateSet getAccessibleStateSet() {
AccessibleStateSet states = new AccessibleStateSet();
states.add(AccessibleState.ENABLED);
states.add(AccessibleState.VISIBLE);
states.add(AccessibleState.SHOWING);
return states;
}
@Override
public int getAccessibleIndexInParent() {
return 0;
}
@Override
public int getAccessibleChildrenCount() {
return 0;
}
@Override
public Accessible getAccessibleChild(int i) {
return null;
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Custom Accessible Component");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new CustomAccessibleComponent());
frame.pack();
frame.setVisible(true);
}
}import javax.accessibility.*;
import javax.swing.*;
import java.awt.*;
import java.util.Hashtable;
public class AccessibilityUtils {
/**
* 为组件设置完整的可访问性信息
*/
public static void makeComponentAccessible(JComponent component,
String name,
String description,
String tooltip) {
AccessibleContext context = component.getAccessibleContext();
// 设置基本属性
context.setAccessibleName(name);
context.setAccessibleDescription(description);
// 设置工具提示(也用于可访问性)
component.setToolTipText(tooltip);
// 设置键盘助记符(如果适用)
if (component instanceof AbstractButton) {
AbstractButton button = (AbstractButton) component;
// 这里可以设置助记符,例如:button.setMnemonic('C');
}
}
/**
* 为容器中的所有组件设置可访问性
*/
public static void makeContainerAccessible(Container container) {
Component[] components = container.getComponents();
for (Component comp : components) {
if (comp instanceof JComponent) {
JComponent jcomp = (JComponent) comp;
String className = comp.getClass().getSimpleName();
makeComponentAccessible(jcomp,
className + " Component",
"This is a " + className + " with accessibility support",
className + " tooltip");
}
// 递归处理子容器
if (comp instanceof Container) {
makeContainerAccessible((Container) comp);
}
}
}
/**
* 打印组件的可访问性信息(用于调试)
*/
public static void printAccessibilityInfo(JComponent component) {
AccessibleContext context = component.getAccessibleContext();
System.out.println("=== Accessibility Info for " + component.getClass().getSimpleName() + " ===");
System.out.println("Name: " + context.getAccessibleName());
System.out.println("Description: " + context.getAccessibleDescription());
System.out.println("Role: " + context.getAccessibleRole());
System.out.println("State: " + context.getAccessibleStateSet());
System.out.println("Children Count: " + context.getAccessibleChildrenCount());
System.out.println();
}
/**
* 创建具有完整可访问性支持的示例界面
*/
public static JPanel createAccessibleDemoPanel() {
JPanel panel = new JPanel(new GridLayout(3, 2, 10, 10));
// 创建各种组件并设置可访问性
JButton button = new JButton("Submit");
makeComponentAccessible(button, "Submit Button",
"Click to submit the form", "Submit form data");
JTextField textField = new JTextField(15);
makeComponentAccessible(textField, "Name Input Field",
"Enter your name here", "Type your name");
JCheckBox checkBox = new JCheckBox("I agree to terms");
makeComponentAccessible(checkBox, "Agreement Checkbox",
"Check to agree to terms and conditions",
"Accept terms and conditions");
JComboBox<String> comboBox = new JComboBox<>(new String[]{"Option 1", "Option 2", "Option 3"});
makeComponentAccessible(comboBox, "Selection Dropdown",
"Choose an option from the list", "Select an option");
JSlider slider = new JSlider(0, 100, 50);
makeComponentAccessible(slider, "Value Slider",
"Adjust the value using the slider", "Slide to adjust value");
JProgressBar progressBar = new JProgressBar(0, 100);
progressBar.setValue(75);
makeComponentAccessible(progressBar, "Progress Indicator",
"Shows the current progress", "Progress display");
panel.add(button);
panel.add(textField);
panel.add(checkBox);
panel.add(comboBox);
panel.add(slider);
panel.add(progressBar);
return panel;
}
public static void main(String[] args) {
JFrame frame = new JFrame("Accessibility Utils Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel demoPanel = createAccessibleDemoPanel();
frame.add(demoPanel);
// 打印所有组件的可访问性信息
makeContainerAccessible(demoPanel);
printAccessibilityInfo(demoPanel);
frame.pack();
frame.setVisible(true);
}
}1、AccessibleContext 是核心类,提供组件的可访问性信息
2、所有 Swing 组件默认都实现了 Accessible 接口
3、设置 accessibleName 和 accessibleDescription 对屏幕阅读器至关重要
4、工具提示文本也会被辅助技术使用
5、键盘导航(助记符和快捷键)是可访问性的重要部分