Я написал программу для тренировки потоков в Java FX, но я хотел добавить лучшую доступность.Я использую JAWS, поэтому мне хотелось бы, чтобы при динамическом обновлении текстовой области я хотел, чтобы программа чтения с экрана объявляла о новом тексте.Я нашел ответ о переполнении стека, поэтому я не знаю, считается ли этот пост дубликатом.Проблема в том, что данное решение работает только для озвучивания, я сам не тестировал, поэтому точно не знаю.Однако JAWS и NVDA вообще не работают с данным кодом.
Вот пост, который я уже нашел о переполнении стека:
Доступное чтение экрана вывода консоли JavaFX
В ответе в этом посте используется метод
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