2017-08-24 1 views
0

J'ai construit une interface graphique en JavaFX avec FXML pour exécuter un tas de différents scripts Python. Les scripts Python collectent en permanence des données à partir d'un périphérique et les impriment sur la console, en boucle, entre 10 et 70 Hz, en fonction du script exécuté, et ils ne s'arrêtent pas d'eux-mêmes.JavaFX show looping sortie d'impression Python

Je souhaite que l'utilisateur final puisse cliquer sur un bouton de mon interface graphique qui lance les scripts et leur permette de voir la sortie. Actuellement, le mieux que j'ai fait était d'utiliser Runtime.exec() avec la commande "cmd /c start cmd /k python some_script.py" qui ouvre l'invite de commande Windows, exécute python some_script.py dedans, et maintient l'invite de commande ouverte afin que vous puissiez voir la sortie. Le problème avec ceci est qu'il ne fonctionne que sur Windows (mon OS) mais j'ai besoin d'un support universel pour le système d'exploitation et qu'il repose sur Java en démarrant un programme externe que j'entends n'est pas très élégant.

J'ai alors essayé de remédier à cette situation en exécutant la commande python some_script.py en Java, capturant la sortie de processus avec BufferedReader, la création d'une nouvelle scène JavaFX avec juste un TextArea dans un AnchorPane être un pseudo-Java console, puis appeler .setText() sur cette TextArea pour mettre le script en sortie. Cela a fonctionné, mais j'ai rencontré beaucoup de problèmes car l'écriture sur la console JavaFX sautait en gros morceaux de plusieurs dizaines de lignes au lieu d'écrire ligne par ligne alors que le code Python faisait des appels Print(). En outre, j'ai eu un tas de NullPointerException et ArrayIndexOutOfBoundsException quelque peu au hasard en ce que Java écrirait quelques centaines de lignes correctement, mais ensuite jeter ces erreurs et geler le programme. Je suis assez sûr que ces deux problèmes étaient dus à avoir autant de données à des débits aussi élevés qui ont débordé le tampon BufferedReader et/ou le cache TextArea.setText() ou quelque chose de similaire.

Ce que je veux savoir, c'est quelle approche je devrais prendre à ce sujet. Je ne peux pas migrer le code Python vers Java car il dépend de la bibliothèque Python de quelqu'un d'autre pour collecter ses données. Devrais-je essayer de garder l'idée de la pseudo-console Java et voir si je peux faire ce travail? Devrais-je revenir à l'ouverture d'une fenêtre d'invite de commande à partir de Java et à l'exécution des scripts Python, puis ajouter le support pour faire la même chose avec Terminal dans Mac et Linux? Y a-t-il une meilleure approche à laquelle je n'ai pas pensé? Est-ce que l'idée d'avoir du code Java appelle le code Python et gère sa sortie juste dégoûtant et une idée horrible? S'il vous plaît laissez-moi savoir si vous souhaitez voir un code (il y en a beaucoup) ou si je peux clarifier quelque chose, et je vais essayer de mon mieux pour répondre rapidement. Je vous remercie!

Répondre

0

Ma solution consistait à toujours appeler le code Python à partir de Java Processbuilder, mais utiliser l'option -u comme python -u scriptname.py pour spécifier la sortie Python non tamponnée.