Приложение реагирует на действия, которые происходят на геймпаде. Когда кнопка нажата, что-то происходит в пользовательском интерфейсе. Но я столкнулся с проблемой с зависанием приложения или исключением "java.lang.IllegalStateException: Not on FX application thread".
Чтобы исправить это, я попытался использовать следующие подходы: Platform.runLater()
и Task
. Но это не помогло.
Вот код проблемы:
public class GamepadUI extends Application{
private static final int WIDTH = 300;
private static final int HEIGHT = 213;
private Pane root = new Pane();
private ImageView iv1 = new ImageView();
private boolean isXPressed = false;
@Override
public void start(Stage stage) throws Exception {
initGUI(root);
Scene scene = new Scene(root, WIDTH, HEIGHT);
stage.setScene(scene);
stage.setResizable(false);
stage.show();
}
public void pressBtn() {
if(!isXPressed) {
iv1.setVisible(true);
isXPressed = true;
}
}
public void releaseBtn() {
if(isXPressed) {
iv1.setVisible(false);
isXPressed = false;
}
}
private void initGUI(final Pane root) {
Image image = new Image(Props.BUTTON);
iv1.setImage(image);
iv1.setLayoutX(198);
iv1.setLayoutY(48);
iv1.setVisible(false);
root.getChildren().add(iv1);
runTask();
}
public void runTask() {
Task task = new Task<Void>() {
@Override
protected Void call() throws Exception {
initStubGamepad();
return null;
}
};
new Thread(task).start();
}
public static void main(String[] args) {
launch(args);
}
public void initStubGamepad() {
Random rnd = new Random();
try {
while (true) {
if (rnd.nextInt(30) == 3) {
pressBtn();
} else if (rnd.nextInt(30) == 7) {
releaseBtn();
}
}
} catch (Exception ex) {
System.out.println("Exception: " + ex);
}
}
}
initStubGamepad()
эмулирует просмотр активности кнопок геймпада. Когда пользователь нажимает любую кнопку (rnd.nextInt(30) == 3
) - изображение появляется в пользовательском интерфейсе. Когда пользователь отпускает эту кнопку (rnd.nextInt(30) == 7
) - изображение исчезает из пользовательского интерфейса.
В случае, если выше java.lang.IllegalStateException: Not on FX application thread
. Если вы измените runTask() на что-то вроде этого:
Platform.runLater(new Runnable() {
@Override
public void run() {
initStubGamepad();
}
});
Затем приложение зависает или даже основной пользовательский интерфейс вообще не появится, но активность геймпада продолжается.
Я хочу просто показать/скрыть разные образы, когда какая-либо активность обнаружена на геймпаде (кстати, нет способа контролировать активность геймпада, кроме опроса геймпада в бесконечном цикле). Что я ошибся