# Accessibility

> For the complete documentation index, see [llms.txt](https://plugins.jetbrains.com/docs/intellij/llms.txt).

Accessibility means building user interfaces that everyone can use, regardless of their abilities. It allows people with different needs, such as those who rely on assistive technologies or need keyboard-only navigation, to fully interact with the product. Follow these guidelines, based on [industry standards](https://www.w3.org/TR/WCAG22/), to ensure the UI is accessible for all.

## Keyboard accessibility

All functionality must be operable by using only the keyboard. People who have trouble using a mouse, including those who are blind, have low vision, or have motor disabilities, rely on keyboard navigation to effectively use the interface.

### Focus basics

The basic way to interact with the UI by using the keyboard is to switch focus between components with `Tab` and `Shift+Tab`. For some components, such as lists, drop-down menus, or tables, arrow keys can also be used to navigate between items. Once a component is focused, it can be activated by pressing `Space`.

Make all interactive elements focusable to achieve [full keyboard operability](https://www.w3.org/WAI/WCAG22/Understanding/keyboard.html). This includes buttons, checkboxes, text fields, lists, tables, dropdowns, and other controls that users can interact with.

Non-interactive components, such as labels and panels, should not be focusable. However, in some cases, they can be focusable to let screen reader users access important information. Use [ScreenReader.isActive()](https://github.com/JetBrains/intellij-community/tree/idea/263.7307.200/platform/util/ui/src/com/intellij/util/ui/accessibility/ScreenReader.java) to adjust the behavior only for screen reader users.

### Keyboard traps

Make the UI traversable in a cycle without trapping the keyboard focus. A [keyboard focus trap](https://www.w3.org/WAI/WCAG22/Understanding/no-keyboard-trap.html) occurs when a user cannot navigate away from a component by using the standard keyboard navigation. This prevents them from accessing other parts of the interface.

Ensure that a user can always navigate away from any focusable component by using `Tab`, `Shift+Tab`, or `Escape`. For instance, continuously pressing `Tab` or `Shift+Tab` in a dialog should result in cycling through all components and returning to the starting point. To break out of such focus loops, use `Escape` to close dialogs and popups, or move focus back from a tool window to the editor.

### Managing focus

When new content appears, such as popups, modal dialogs, or dynamic content, ensure that:

* Focus is moved to the new content, or there is a way to reach it by using only the keyboard.

* Focus is not moved unexpectedly when users are interacting with components like lists or dropdowns to avoid a [change of context](https://www.w3.org/WAI/WCAG22/Understanding/on-focus.html#dfn-changes-of-context).

## Assistive technology support

Assistive technologies, such as screen readers and voice control, rely on accessibility metadata provided by UI components. For example, a checkbox might be announced by screen readers as "Don't ask again, checkbox, not checked, Alt+D". Voice control users can say "Press Don't ask again" to activate the checkbox. This integration is enabled by properly defined accessible metadata.

Follow these guidelines to ensure that users of assistive technology can fully interact with the UI.

### Accessible properties

Each UI component has an associated [javax.accessibility.AccessibleContext](https://docs.oracle.com/en/java/javase/21/docs/api/java.desktop/javax/accessibility/AccessibleContext.html) object that defines properties for assistive technologies. The accessible context can also implement [Accessible*](https://docs.oracle.com/en/java/javase/21/docs/api/java.desktop/javax/accessibility/package-summary.html#class-summary) interfaces to provide additional metadata or ways for assistive technologies to interact with the component.

> **Note:**
> For [common UI components](components.html), basic accessibility support is often already implemented. But when creating custom components or extending existing ones, you may need to extend the accessible context or modify its properties.

Example of customizing the accessible context and its properties:

Kotlin:

```KOTLIN
class ActionLink : JButton() {
  override fun getAccessibleContext(): AccessibleContext {
    if (accessibleContext == null) {
      accessibleContext = object : AccessibleAbstractButton() {
        override fun getAccessibleRole() = AccessibleRole.HYPERLINK
        override fun getAccessibleValue() = null
      }
    }
    return accessibleContext
  }
}

val link = ActionLink()
link.accessibleContext.accessibleName = "Open in browser"
```

Java:

```JAVA
class ActionLink extends JButton {
  @Override
  public AccessibleContext getAccessibleContext() {
    if (accessibleContext == null) {
      accessibleContext = new AccessibleAbstractButton() {
        @Override
        public AccessibleRole getAccessibleRole() {
          return AccessibleRole.HYPERLINK;
        }

        @Override
        public AccessibleValue getAccessibleValue() {
          return null;
        }
      };
    }
    return accessibleContext;
  }
}

ActionLink link = new ActionLink();
link.getAccessibleContext().setAccessibleName("Open in browser");
```

#### Accessible name and description

An [accessible name](https://docs.oracle.com/en/java/javase/21/docs/api/java.desktop/javax/accessibility/AccessibleContext.html#getAccessibleName()) is the label that defines the component's purpose for assistive technology users. Set a clear and descriptive accessible name for all focusable components.

For example, a simple button with text should have that text as its accessible name. For a text field with a label in front of it, the accessible name should be the label's text. A list without a visible title should still have an accessible name that describes its content.

In many cases, the accessible name is already taken implicitly from the following sources:

* The text property of components such as labels or buttons.

* Tooltip text.

* The label of the component that was set by `JLabel.setLabelFor()`.

If the name was not applied implicitly, set it by calling `AccessibleContext.setAccessibleName()` or by overriding `AccessibleContext.getAccessibleName()`:

Kotlin:

```KOTLIN
class AccessibleCheckBox : AccessibleJLabel() {
  override fun getAccessibleName() = myLabel.text
}

checkBox.accessibleContext.accessibleName = "Don't ask again"
```

Java:

```JAVA
class AccessibleCheckBox extends AccessibleJLabel {
  @Override
  public String getAccessibleName() {
    return myLabel.getText();
  }
}

checkBox.getAccessibleContext().setAccessibleName("Don't ask again");
```

Tips for choosing an accessible name:

* Don't include the component's role in the accessible name. For example, for a password text field, set the name as "Password" instead of "Password text field."

* For complex components, include all visible information in the accessible name. For example, for a panel that consists of a title, subtitle, and icon, combine all these parts in the accessible name.

An accessible description provides additional context, such as instructions, keyboard shortcuts, placeholders, or explanatory text. Use it for supplementary information that helps users understand how to interact with the component.

The accessible description is set similarly to the accessible name, either by calling `AccessibleContext.setAccessibleDescription()` or by overriding `AccessibleContext.getAccessibleDescription()`.

#### Accessible role

The accessible role tells assistive technologies what type of component they are interacting with. Use the [AccessibleRole](https://docs.oracle.com/en/java/javase/21/docs/api/java.desktop/javax/accessibility/AccessibleRole.html) value that correctly represents the component's function.

The accessible role can be changed by overriding `AccessibleContext.getAccessibleRole()`:

Kotlin:

```KOTLIN
class AccessibleCheckBox : AccessibleJLabel() {
  override fun getAccessibleRole() = AccessibleRole.CHECK_BOX
}
```

Java:

```JAVA
class AccessibleCheckBox extends AccessibleJLabel {
  @Override
  public AccessibleRole getAccessibleRole() {
    return AccessibleRole.CHECK_BOX;
  }
}
```

Tips for customizing the role:

* Use `AccessibleRole.LABEL` for plain text content and `AccessibleRole.TEXT` for text fields and text areas that are editable or support selection.

* Set an appropriate button role: `AccessibleRole.PUSH_BUTTON`, `AccessibleRole.RADIO_BUTTON`, `AccessibleRole.TOGGLE_BUTTON`, or `AccessibleRole.HYPERLINK`.

#### Accessible state

The [accessible state](https://docs.oracle.com/en/java/javase/21/docs/api/java.desktop/javax/accessibility/AccessibleState.html) communicates the component's current condition to assistive technologies. For example, it can tell screen reader users that the component is selected, expanded, or editable.

Adjust the component's state set by overriding `AccessibleContext.getAccessibleStateSet()`:

Kotlin:

```KOTLIN
class AccessibleCheckBox : AccessibleJLabel() {
  override fun getAccessibleStateSet(): AccessibleStateSet {
    val set = super.getAccessibleStateSet()
    if (myChecked) {
      set.add(AccessibleState.CHECKED)
    }
    return set
  }
}
```

Java:

```JAVA
class AccessibleCheckBox extends AccessibleJLabel {
  @Override
  public AccessibleStateSet getAccessibleStateSet() {
    AccessibleStateSet set = super.getAccessibleStateSet();
    if (myChecked) {
      set.add(AccessibleState.CHECKED);
    }
    return set;
  }
}
```

Notify assistive technologies when the state changes:

Kotlin:

```KOTLIN
accessibleContext.firePropertyChange(
  AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  null,
  AccessibleState.CHECKED
)
```

Java:

```JAVA
getAccessibleContext().firePropertyChange(
  AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  null,
  AccessibleState.CHECKED
);
```

#### Accessible interfaces

Advanced accessibility features are provided through specialized interfaces, such as `AccessibleAction`, `AccessibleText`, `AccessibleSelection`, and `AccessibleValue`. These are typically needed when implementing custom components from scratch. Refer to the [list](https://docs.oracle.com/en/java/javase/21/docs/api/java.desktop/javax/accessibility/package-summary.html) of available interfaces to determine whether any need to be implemented.

> **Note:**
> Look at similar Swing components to see which interfaces they implement. For example, when working on a new slider-like component, check the interfaces implemented by [JSlider.AccessibleJSlider](https://docs.oracle.com/en/java/javase/21/docs/api/java.desktop/javax/swing/JSlider.AccessibleJSlider.html).

### Announcing live changes

Screen readers announce accessible property changes of the currently focused component automatically. For example, when a user checks a checkbox, the screen reader announces the new state. This happens through property change events fired by the component.

However, in some cases, users need to be notified of changes outside the focused component. Or the event to notify about doesn't fit into existing property change support.

For these scenarios, use [AccessibleAnnouncerUtil.announce()](https://github.com/JetBrains/intellij-community/tree/idea/263.7307.200/platform/util/ui/src/com/intellij/util/ui/accessibility/AccessibleAnnouncerUtil.java) to make screen readers announce a specific string.

Kotlin:

```KOTLIN
if (AccessibleAnnouncerUtil.isAnnouncingAvailable()) {
  AccessibleAnnouncerUtil.announce(mySearchPanel, "No results found", true)
}
```

Java:

```JAVA
if (AccessibleAnnouncerUtil.isAnnouncingAvailable()) {
  AccessibleAnnouncerUtil.announce(mySearchPanel, "No results found", true);
}
```

Common cases for using announcements:

* Error messages or validation results.

* Notifications or popups that are shown but don't receive keyboard focus.

* Background task completion.

* Search or filtering results.

## Tools

### Screen readers

The IntelliJ Platform supports NVDA and JAWS screen readers on Windows, and VoiceOver on macOS. Test the UI with a screen reader to verify that all functionality is available and that the announced information is correct and complete.

> **Tip:**
> Learn more about screen reader functionality and commands from their official user guides: [NVDA](https://download.nvaccess.org/releases/2025.1.2/documentation/userGuide.html), [JAWS](https://support.freedomscientific.com/products/blindness/jawsdocumentation), and [VoiceOver](https://support.apple.com/guide/voiceover/welcome/mac).

### UI Inspector

Use the [UI Inspector](internal-ui-inspector.html) to examine accessible properties of UI components. You can also perform an [accessibility audit](internal-ui-inspector.html#accessibility-checks) to check for common issues and get information on how to resolve them.

