IntelliJ Platform Plugin SDK Help

Accessibility

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, 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. 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() 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 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.

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 object that defines properties for assistive technologies. The accessible context can also implement Accessible* interfaces to provide additional metadata or ways for assistive technologies to interact with the component.

Example of customizing the accessible context and its properties:

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"
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 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():

class AccessibleCheckBox : AccessibleJLabel() { override fun getAccessibleName() = myLabel.text } checkBox.accessibleContext.accessibleName = "Don't ask again"
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 value that correctly represents the component's function.

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

class AccessibleCheckBox : AccessibleJLabel() { override fun getAccessibleRole() = AccessibleRole.CHECK_BOX }
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 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():

class AccessibleCheckBox : AccessibleJLabel() { override fun getAccessibleStateSet(): AccessibleStateSet { val set = super.getAccessibleStateSet() if (myChecked) { set.add(AccessibleState.CHECKED) } return set } }
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:

accessibleContext.firePropertyChange( AccessibleContext.ACCESSIBLE_STATE_PROPERTY, null, AccessibleState.CHECKED )
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 of available interfaces to determine whether any need to be implemented.

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 that you want to notify about doesn't fit into existing property change support.

For these scenarios, use AccessibleAnnouncerUtil.announce() to make screen readers announce a specific string.

if (AccessibleAnnouncerUtil.isAnnouncingAvailable()) { AccessibleAnnouncerUtil.announce(mySearchPanel, "No results found", true) }
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.

UI Inspector

Use the UI Inspector to examine accessible properties of UI components. You can also perform an accessibility audit to check for common issues and get information on how to resolve them.

19 September 2025