Java Swing集成JavaFX后屏幕阅读器无法读取组件内容的解决方案咨询
Java Swing集成JavaFX后屏幕阅读器无法读取组件内容的解决方案咨询
大家好,我们团队维护着一个Java Swing桌面应用,最近为了提升UI质感,把部分页面重构为JavaFX实现,并且通过JFXPanel完成了Swing与JavaFX的桥接集成。集成过程很顺利,但现在遇到了一个棘手的无障碍访问问题:屏幕阅读器(比如NVDA)完全无法读取JavaFX组件的文本和描述信息。
我们已经按照要求给所有JavaFX组件都配置了无障碍相关的文本和描述,但问题依然存在。想请教一下有没有遇到过类似问题的朋友,或者了解相关技术的大佬,能给我们一些解决思路或者具体的方案?
下面是我们用来测试的示例代码:
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); } }
备注:内容来源于stack exchange,提问作者chetan gangurde




