chetan gangurde
chetan gangurde

Reputation: 19

Screen reader unable to read text from javaFX desktop application integrated with Java Swing

We have Java Swing desktop application and we upgraded some pages designed using JavaFX and for better UI design and integrated JavaFx using JFXPanel as bridge for Java Swing. Integration successfully done but screen reader unable to read JavaFx components text and description. We already added All accessibility text and description but still screen reader like NVDA unable to read Javafx page. Can you please help and suggest some solution how we can proceed with it.

I'm putting sample code which we tried

package org.example.javafx.hellojavafx;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.AccessibleRole;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.BorderPane;
import org.controlsfx.control.PopOver;

import javax.swing.*;
import java.awt.*;

public class AccessiblePaneExample {

  public static void main(String[] args) {
    System.setProperty("javafx.accessible.force", "true");
    SwingUtilities.invokeLater(() -> {
      JFrame frame = new JFrame("Accessible Pane Example");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setSize(800, 600);
      frame.setLayout(new BorderLayout());

      JFXPanel fxPanel = new JFXPanel();
      frame.add(fxPanel, BorderLayout.CENTER);

      Platform.runLater(() -> initFX(fxPanel));

      frame.setVisible(true);
    });
  }

  private static void initFX(JFXPanel fxPanel) {
    // Button
    Button button = new Button("Click Me");
    button.setAccessibleRole(AccessibleRole.BUTTON);
    button.setAccessibleRoleDescription("A button that can be clicked");
    button.setAccessibleHelp("Clickable Button");

    // ComboBox
    ComboBox<String> comboBox = new ComboBox<>();
    comboBox.getItems().addAll("Item 1", "Item 2", "Item 3", "Item 4");
    comboBox.setAccessibleRole(AccessibleRole.COMBO_BOX);
    comboBox.setAccessibleRoleDescription("A combo box for selecting items");
    comboBox.setAccessibleHelp("Item Selection ComboBox");

    // BarChart
    final CategoryAxis xAxis = new CategoryAxis();
    final NumberAxis yAxis = new NumberAxis();
    final BarChart<String, Number> barChart = new BarChart<>(xAxis, yAxis);
    barChart.setTitle("Item Summary");
    xAxis.setLabel("Item");
    yAxis.setLabel("Value");

    XYChart.Series<String, Number> series = new XYChart.Series<>();
    series.setName("2023");
    series.getData().add(new XYChart.Data<>("Item 1", 50));
    series.getData().add(new XYChart.Data<>("Item 2", 80));
    series.getData().add(new XYChart.Data<>("Item 3", 30));
    series.getData().add(new XYChart.Data<>("Item 4", 60));

    barChart.getData().add(series);
    barChart.setAccessibleRoleDescription("Bar chart showing item summary");
    barChart.setAccessibleHelp("Bar chart showing item summary");

    for (XYChart.Data<String, Number> data : series.getData()) {
      PopOver popOver = new PopOver();
      popOver.setContentNode(new javafx.scene.control.Label(data.getXValue() + ": " + data.getYValue()));
      data.getNode().setOnMouseEntered(event -> popOver.show(data.getNode()));
      data.getNode().setOnMouseExited(event -> popOver.hide());
      data.getNode().setAccessibleRole(AccessibleRole.TEXT);
      data.getNode().setAccessibleRoleDescription(data.getXValue() + ": " + data.getYValue());
      data.getNode().setAccessibleHelp(data.getXValue() + ": " + data.getYValue());
    }

    // Layout
    BorderPane root = new BorderPane();
    root.setTop(button);
    root.setCenter(comboBox);
    root.setBottom(barChart);
    root.setFocusTraversable(true);

    Scene scene = new Scene(root, 800, 600);
    fxPanel.setScene(scene);
  }
}

Upvotes: 1

Views: 52

Answers (0)

Related Questions