我写了一个程序来练习Java FX中的线程,但是我想增加更好的可访问性。我使用JAWS,所以我想要的是当我的文本区域动态更新时,我希望我的屏幕阅读器宣布新文本。我在堆栈溢出时找到了答案,所以我不知道这篇文章是否被认为是重复的。问题在于给出的解决方案仅适用于画外音,我自己没有测试过,所以我不确定。但是,JAWS和NVDA根本无法使用给定的代码。
这是我在堆栈溢出时发现的帖子:
Accessible screenreading of JavaFX "console" output
本文中的答案使用
TextArea.executeAccessibleAction(AccessibleAction.SET_TEXT_SELECTION,
开始,结束);
方法。如前所述,这是行不通的。有谁知道如何让Windows屏幕阅读器说出Java FX TextArea中的更新文本?
这是我的代码,没有任何可访问性支持尝试:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.AccessibleAction;
import javafx.scene.AccessibleRole;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.control.TextArea;
import javafx.event.EventHandler;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.KeyCode;
import javafx.application.Platform;
public class KeyPresser extends Application implements EventHandler<KeyEvent> {
private class MyRunnable implements Runnable {
public void run() {
try {
while (true) {
Platform.runLater(new AppendTextRunnable("Message from " + Thread.currentThread().getName() + "\n"));
Thread.sleep(1000);
}//end while loop
} catch(InterruptedException ie) {
Platform.runLater(new AppendTextRunnable(Thread.currentThread().getName() + " gets interrupted! Terminate!\n"));
}//end try catch
}//end method
}//end nested class
private class AppendTextRunnable implements Runnable {
private String text;
private AppendTextRunnable(String text) {
this.text = text;
}//end constructor
@Override
public void run() {
KeyPresser.this.outputArea.appendText(this.text);
}//end method
}//end nested class
private int counter = 0;
private Thread t1, t2;
private TextArea outputArea;
public static void main(String[] args) {
Application.launch(args);
} //end method
@Override
public void start(Stage primaryStage) {
ScrollPane scrollPane = new ScrollPane();
Scene scene = new Scene(scrollPane, 500, 500);
this.outputArea = new TextArea();
this.outputArea.setEditable(false);
scrollPane.setContent(this.outputArea);
scrollPane.setVbarPolicy(ScrollBarPolicy.ALWAYS);
scene.setOnKeyReleased(this);
primaryStage.setScene(scene);
primaryStage.setTitle ("the Key Presser");
primaryStage.show();
this.t1 = new Thread(new MyRunnable());
this.t2 = new Thread(new MyRunnable());
this.t1.setDaemon(true);
this.t2.setDaemon(true);
this.t1.start();
this.t2.start();
} //end method
@Override
public void handle(KeyEvent key) {
KeyCode keyCode = key.getCode();
if (key.getEventType() == KeyEvent.KEY_RELEASED && !keyCode.isNavigationKey()) {
this.counter++;
if (this.counter == 1) {
this.t1.interrupt();
} else if (this.counter == 2) {
this.t2.interrupt();
} else if (this.counter == 3) {
Platform.runLater(new AppendTextRunnable("All threads are terminated\n"));
}//end else if
}//end if
}//end method
} //end class