IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaFX Discussion :

Bonnes pratiques pour exécuter une tâche de fond en JavaFX, un tutoriel de Fabrice Bouyé


Sujet :

JavaFX

  1. #1
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut Bonnes pratiques pour exécuter une tâche de fond en JavaFX, un tutoriel de Fabrice Bouyé
    Bonjour,
    je vous propose un nouvel article concernant JavaFX, cette fois-ci sur les bonnes pratiques pour exécuter une tâche de fond, de longue durée ou récurrente sans pour autant bloquer votre interface graphique :

    http://fabrice-bouye.developpez.com/...thread-javafx/

    Vous pouvez profiter de ce message pour partager vos commentaires. Cet article a été commencé sous JavaFX 2.2 il y a plus d'un an et j'ai ensuite mis à jour certaines parties pour JavaFX 8 qui a entre autres rajouté une classe permettant d’effectuer des tâches récurrentes, donc, surtout, n’hésitez pas à m'indiquer toutes erreurs, omissions ou encore des éventuels anomalies.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  2. #2
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2014
    Messages : 47
    Points : 31
    Points
    31
    Par défaut Problème avec Service
    Bonjour, j'ai lu ton tutoriel sur les Service et les Task mais j'ai tout de même un problème avec l'un des mes programmes ...
    J'obtiens le message d'erreur suivant : Exception in thread "MQTT Call: ID1" java.lang.IllegalStateException: Not on FX application thread; currentThread = MQTT Call: ID1
    Je créé pourtant un Service qui établi la connection avec la base de donnée MQTT et qui souscrit à une valeur de la base de donnée mqtt. Voici la partie de code qui pose problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    import javafx.concurrent.Service;
    import javafx.concurrent.Task;
    import javafx.scene.image.ImageView;
    import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
    import org.eclipse.paho.client.mqttv3.MqttCallback;
    import org.eclipse.paho.client.mqttv3.MqttClient;
    import org.eclipse.paho.client.mqttv3.MqttException;
    import org.eclipse.paho.client.mqttv3.MqttMessage;
     
    public class Led extends ImageView implements MqttCallback {
     
        private static final String BROKER = "tcp://255.255.255.255:1883";  // adresse ip du serveur mqtt
     
        private final String name;
        private final String id;
        private static int idCount = 1;
     
        public Led(String name) {
            this.name = name.toUpperCase();
            this.id = "IDLED"+idCount++;
            this.getStyleClass().add("led_on");
            Service<Void> connectionMqtt = new Service<Void>() {
     
                @Override
                protected Task<Void> createTask() {
                    return new Task<Void>() {
     
                        @Override
                        protected Void call() throws Exception {
                            try {
                                MqttClient client = new MqttClient(BROKER, Led.this.id);
                                client.setCallback(Led.this);
                                client.connect();
                                client.subscribe("A000009/"+Led.this.name);
                            } catch(MqttException e) {
                                e.printStackTrace();
                            }
                            return null;
                        }                    
                    };
                }            
            };
            connectionMqtt.start();
        }
     
        @Override
        public void connectionLost(Throwable thrwbl) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
     
        @Override
        public void messageArrived(String string, MqttMessage mm) throws Exception {
            if (mm.toString().equals("1"))
                this.getStyleClass().setAll("led_on");
            else
                this.getStyleClass().setAll("led_off");
        }
     
        @Override
        public void deliveryComplete(IMqttDeliveryToken imdt) {
            throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
        }
     
    }
    Alors que la partie de code qui permet de publier un message à la base de donnée mqtt ne pose aucun soucis et ne renvoie par d'exception :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    import javafx.scene.control.Button;
    import org.eclipse.paho.client.mqttv3.MqttClient;
    import org.eclipse.paho.client.mqttv3.MqttException;
    import org.eclipse.paho.client.mqttv3.MqttMessage;
     
    public class Switch extends Button {
     
        private static final String BROKER = "tcp://255.255.255.255:1883";
        private static final int QOS = 2;
     
        private String name;
        private String status = "ON";
        private final String id;
        private static int idCount = 1;
        private MqttClient client;
     
        public Switch(String name) {
            this.name = name.toUpperCase();
            this.id = "IDSWI"+idCount++;
            try {
                client = new MqttClient(BROKER, this.id);
            } catch(MqttException e) {
                e.printStackTrace();
            }
        }
     
        public void publish() {
            try {
                client.connect();
                MqttMessage message = new MqttMessage(status.getBytes());
                status = (status.equals("ON")) ? "OFF" : "ON";
                message.setQos(QOS);
                client.publish("A000009/"+this.name, message);
                client.disconnect();
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
     
    }
    L'idée est que le LED réagisse au changement de valeur de la base de donnée mqtt

    Merci d'avance

  3. #3
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Pour rappel, le corps de la Task s’exécute dans un autre thread.

    D’après ton erreur, ici tu appelles, depuis un autre thread, quelques chose qui devrait en fait s'effectuer dans le JavaFX Application Thread.

    Donc je suppose, a priori, qu'il s'agit de quelque chose que tu appelles dans ta tache (puisque tu n'as pas donne de trace ou de numéro de ligne pour cette erreur) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    MqttClient client = new MqttClient(BROKER, Led.this.id);
    client.setCallback(Led.this);
    client.connect();
    client.subscribe("A000009/"+Led.this.name);
    Il faudrait donc trouver ce dont il s'agit.
    Ça serait plus facile si je savais quelle ligne provoque l'erreur
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2014
    Messages : 47
    Points : 31
    Points
    31
    Par défaut
    Alors, niveau des erreurs j'obtiens ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    Exception in thread "MQTT Call: IDLED1" java.lang.IllegalStateException: Not on FX application thread; currentThread = MQTT Call: IDLED1
    	at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:204)
    	at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:364)
    	at javafx.scene.Scene.addToDirtyList(Scene.java:485)
    	at javafx.scene.Node.addToSceneDirtyList(Node.java:424)
    	at javafx.scene.Node.impl_markDirty(Node.java:415)
    	at javafx.scene.Node.impl_geomChanged(Node.java:3784)
    	at javafx.scene.image.ImageView.access$300(ImageView.java:143)
    	at javafx.scene.image.ImageView$1.invalidated(ImageView.java:223)
    	at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:111)
    	at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:145)
    	at javafx.scene.image.ImageView.setImage(ImageView.java:189)
    	at javafx.scene.image.ImageView$2.invalidated(ImageView.java:259)
    	at javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:109)
    	at javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:143)
    	at javafx.css.StyleableStringProperty.set(StyleableStringProperty.java:83)
    	at javafx.css.StyleableStringProperty.applyStyle(StyleableStringProperty.java:69)
    	at javafx.css.StyleableStringProperty.applyStyle(StyleableStringProperty.java:45)
    	at javafx.scene.CssStyleHelper.resetToInitialValues(CssStyleHelper.java:452)
    	at javafx.scene.CssStyleHelper.createStyleHelper(CssStyleHelper.java:180)
    	at javafx.scene.Node.reapplyCss(Node.java:8785)
    	at javafx.scene.Node.impl_reapplyCSS(Node.java:8748)
    	at javafx.scene.Node$3.onChanged(Node.java:998)
    	at com.sun.javafx.collections.TrackableObservableList.lambda$new$20(TrackableObservableList.java:45)
    	at com.sun.javafx.collections.TrackableObservableList$$Lambda$54/602720129.onChanged(Unknown Source)
    	at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
    	at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
    	at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
    	at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
    	at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
    	at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
    	at javafx.collections.ModifiableObservableListBase.setAll(ModifiableObservableListBase.java:90)
    	at javafx.collections.ObservableListBase.setAll(ObservableListBase.java:250)
    	at simulateur_v2.Led.messageArrived(Led.java:60)
    	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.handleMessage(CommsCallback.java:354)
    	at org.eclipse.paho.client.mqttv3.internal.CommsCallback.run(CommsCallback.java:162)
    	at java.lang.Thread.run(Thread.java:745)
    J'espère que cela pourra t'aider car moi je bloque ...
    Autre chose... J'ai exécuté le même code sur un PC à mon école et je n'ai eu aucune exception. Est-il possible que cela change d'un environnement à un autre ? (mon netbeans est à la v8.0.1 et celui de l'école à la v8.0)

  5. #5
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Le problème semble avoir donc une cause assez simple : tu as passé ta LED comme callback or cette dernière a reçu un message et a tenté de le traiter dans un thread hors du JavaFX Application Thread. Comme c'est du multithread, l'ordre de séquences d'instructions peut varier suivant plein de facteurs (rapidité/lenteur d’exécution, etc...) donc ça marche d’un coté (école) et pas de l'autre (maison) ; mais le problème persiste : tu as tenté une modification de la scène depuis un thread autre que le JavaFX Application Thread, donc *pouf* ça plante.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    at simulateur_v2.Led.messageArrived(Led.java:60)
    Il faut donc s'assurer que le message arrive et est traité dans le JavaFX Application Thread puisque ce dernier manipule la scène (via la modif de style).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Override
        public void messageArrived(String string, MqttMessage mm) throws Exception {
            if (!Platform.isFxApplicationThread()) {
                Platform.runLater(() -> messageArrived(mm));
            } else {
                String ledStyle = (mm.toString().equals("1")) ? "led_on" : "led_off";
                this.getStyleClass().setAll(ledStyle);
            }
        }
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2014
    Messages
    47
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2014
    Messages : 47
    Points : 31
    Points
    31
    Par défaut
    En fait ça ne fonctionnait pas mieux à mon école, je n'avais juste pas d'exception qui avait été levée donc aucun message ...
    Ça marche avec ta solution merci !
    Je n'ai même pas besoin de me connecter à la db sur un autre thread (il le fait peut-être seul ?)

  7. #7
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Faut voir avec ta méthode de connexion sur la DB. Sur une DB distante avec une connexion réseau lente, un serveur surchargé ou avec une authentification lente, ça pourrait éventuellement prendre un temps non négligeable et donc ça bloquerait ton UI si tu ne passait pas par un service. Ici, on prend tout le temps qu'il faut dans la tache et seul le changement d'état de la LED a lieu dans le JavaFX Application Thread, donc c'est pile poil.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mars 2015
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Mars 2015
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Une remarque sur l'article
    Citation Envoyé par bouye Voir le message
    Bonjour,
    je vous propose un nouvel article concernant JavaFX, cette fois-ci sur les bonnes pratiques pour exécuter une tâche de fond, de longue durée ou récurrente sans pour autant bloquer votre interface graphique :

    http://fabrice-bouye.developpez.com/...thread-javafx/

    Vous pouvez profiter de ce message pour partager vos commentaires. Cet article a été commencé sous JavaFX 2.2 il y a plus d'un an et j'ai ensuite mis à jour certaines parties pour JavaFX 8 qui a entre autres rajouté une classe permettant d’effectuer des tâches récurrentes, donc, surtout, n’hésitez pas à m'indiquer toutes erreurs, omissions ou encore des éventuels anomalies.
    J'ai tout l'article, il est clair et les exemples sont aident à la compréhension des API de concurrence de JavaFX merci pour cet article !
    J'ai juste une remarque sur la récupération de la raison de l'erreur, je pense qu'il s'agit de :
    Pour récupérer la raison de l'échec d'un service, il suffit d'appeler la méthode getException() du service dans le listener ou le callback approprié.
    à la place de
    Pour récupérer la raison de l'échec d'un service, il suffit d'appeler la méthode getError() du service dans le listener ou le callback approprié.

  9. #9
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Merci, ça aura échappé aux multiples relectures (/doh). Je corrige de suite.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  10. #10
    Membre expérimenté
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 076
    Points : 1 521
    Points
    1 521
    Billets dans le blog
    5
    Par défaut
    Très bon tutoriel

    Par contre j'ai un cas qui fonctionne très mal.
    Le code ci dessous charge un scénario pour un jeu et prépare l'affichage. Le chargement dure environ une quinzaine de seconde ce qui est long et peut faire penser que le programme est planté.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
     
    public void chargerJeu(String Nom) {
    		try {
    			FileInputStream fSvg = new FileInputStream(Nom);
    			ObjectInputStream svgBat = new ObjectInputStream(fSvg);
    			scenario = (Jeu) svgBat.readObject();
    			prepareScenario();
     
    			fondDeCarte = new Visu(scenario.getLeTerrain(), scenario.getFeux());
    			vueCarte.setImage(fondDeCarte.getImage());
    			int fig = 0;
    			Pion unite = scenario.getPion(fig++);
    			while (unite != null) {
    				if (!unite.estAlaBase())
    					affiche(unite);
    				if (unite instanceof Vehicule) {
    					((Vehicule) unite).majCarc(paramJeu);
    					if (!unite.estAlaBase())
    						doCalcNouvGraphePour((Vehicule) unite, unite.getX(), unite.getY());
    				}
    				unite = scenario.getPion(fig++);
    			}
    			centreEnXY(0, 0);
    			changeZoom(1);
    			corrigeLocation(0, 0);
    			jgeCtrl.MAJ();
    			jgeCtrl.razMessage();
    			jgeCtrl.setUniteEnMain("", "", null);
    			cmdCtrl.setMiniCarte(fondDeCarte.getImage());
    			cmdCtrl.enableAll(true);
    			cmdCtrl.MAJCmd();
    		} catch (IOException | ClassNotFoundException e1) {
     
    			e1.printStackTrace();
    		}
     
    	}
    Du coups j'ai voulu mettre une boite de dialogue qui montre la progression du chargement. J'ai donc écrit le code ci dessous

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
     
    	private void doLoadGame(String Nom) {
    		final Cursor oldCursor = primaryScene.getCursor();
    		primaryScene.setCursor(Cursor.WAIT);
    		final Stage dialStage = new Stage();
     
     
    		final Service<Void> loadGameService = new Service<Void>() {
     
    			@Override
    			protected Task<Void> createTask() {
    				return new Task<Void>() {
     
    					@Override
    					protected Void call() throws Exception {
    						updateMessage("Lecture");
    						FileInputStream fSvg = new FileInputStream(Nom);
    						ObjectInputStream svgBat = new ObjectInputStream(fSvg);
    						scenario = (Jeu) svgBat.readObject();
    						final int nb = scenario.getNbVehicule() + 2;
    						updateMessage("Graphismes");
    						updateProgress(1, nb);
    						prepareScenario();
    						updateMessage("Carte");
    						fondDeCarte = new Visu(scenario.getLeTerrain(), scenario.getFeux());
    						vueCarte.setImage(fondDeCarte.getImage());
    						updateMessage("Calcul des mouvements");
    						int fig = 0;
    						Pion unite = scenario.getPion(fig++);
    						while (unite != null) {
    							updateProgress(fig + 2, nb);
    							if (!unite.estAlaBase())
    								affiche(unite);
    							if (unite instanceof Vehicule) {
    								((Vehicule) unite).majCarc(paramJeu);
    								if (!unite.estAlaBase())
    									doCalcNouvGraphePour((Vehicule) unite, unite.getX(), unite.getY());
    							}
    							unite = scenario.getPion(fig++);
    						}
    						return null;
    					}
    				};
    			}
    		};
     
    		loadGameService.setOnSucceeded((WorkerStateEvent event) -> {
    			primaryScene.setCursor(oldCursor);
    			centreEnXY(0, 0);
    			changeZoom(1);
    			corrigeLocation(0, 0);
    			jgeCtrl.MAJ();
    			jgeCtrl.razMessage();
    			jgeCtrl.setUniteEnMain("", "", null);
    			cmdCtrl.setMiniCarte(fondDeCarte.getImage());
    			cmdCtrl.enableAll(true);
    			cmdCtrl.MAJCmd();
    			dialStage.close();
    		});
     
    		FXMLLoader loader = new FXMLLoader();
    		URL url = MainFF.class.getResource("view/DialAttente.fxml");
    		loader.setLocation(url);
     
    		try {
    			AnchorPane dial = (AnchorPane) loader.load();
    			dialStage.initModality(Modality.NONE);
    			dialStage.initOwner(primaryStage);
    			Scene scene = new Scene(dial);
    			dialStage.setScene(scene);
    			DialAttenteController dialCtrl = loader.getController();
    			dialCtrl.setDialStage(dialStage, "Charger");
    			dialCtrl.getProg().progressProperty().bind(loadGameService.progressProperty());
    			dialCtrl.getTache().textProperty().bind(loadGameService.messageProperty());
    			dialStage.show();
    			loadGameService.start();
     
    		} catch (IOException e) {
     
    			e.printStackTrace();
    		}
     
    	}
    Mais j'ai un allongement extraordinaire du temps d'exécution supérieur à la minute avec au final des exceptions de pointeur null car il semble terminer la tache avant la fin.
    Je ne comprend pas bien ce qui se passe.
    Il y a des jours où j'éprouve une haine profonde envers microsoft et Apple c'est pas mieux
    Mon modeste site et mes modestes oeuvres sont
    Rémi

  11. #11
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Et, euh, ça plante où, comment, avec quoi comme message ?
    Tu as essayer de tester avec une simple ProgressBar ou un ProgressMonitor dans un Stage au lieu de ton dialogue maison FXML ?
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  12. #12
    Membre expérimenté
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 076
    Points : 1 521
    Points
    1 521
    Billets dans le blog
    5
    Par défaut
    Ca ne plante pas à proprement parler mais ça rame énormément
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    updateMessage("Lecture");
    FileInputStream fSvg = new FileInputStream(Nom);
    ObjectInputStream svgBat = new ObjectInputStream(fSvg);
    scenario = (Jeu) svgBat.readObject();
    Par exemple cette partie mais 3 à 4 fois plus de temps à s'éxécuter. Le message Lecture apparaît rapidement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	final int nb = scenario.getNbVehicule() + 2;
    	updateMessage("Graphismes");
    	updateProgress(1, nb);
    	prepareScenario();
    Quant à cette partie le message et la barre de progression apparaissent bien dans un délai très raisonnable mais après le temps d'exécution de la méthode prepareScenario(); est infini
    Il y a des jours où j'éprouve une haine profonde envers microsoft et Apple c'est pas mieux
    Mon modeste site et mes modestes oeuvres sont
    Rémi

  13. #13
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Est-ce que tu pourrais rajouter un setOnFailed() et voir si une exception est levée STP ?
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  14. #14
    Membre expérimenté
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 076
    Points : 1 521
    Points
    1 521
    Billets dans le blog
    5
    Par défaut
    Voici ce que j'ai ajouté
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    loadGameService.setOnFailed((WorkerStateEvent event) -> {
    			primaryScene.setCursor(oldCursor);
    			System.out.println("Chargement échoué");
    			dialStage.close();
    		});
    Je sort bien avec un échec mais aucune exception n'a été levée.

    Manifestement ça coince dans la méthode prepareScenario. Dans cette méthode j'affecte des images à chacune des unités sur la carte

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    public void prepareScenario() {
    		// figurines.getChildren().removeAll(figurines);
    		while (!figurines.getChildren().isEmpty()) {
    			figurines.getChildren().remove(0);
    		}
     
    		int fig = 0;
    		Pion unite = scenario.getPion(fig++);
    		while (unite != null) {
    			System.out.println("fig n°"+fig+" ="+unite.getFigurine(EtypeFig.STATIC));
     
    			Image imgFig = lesGraph.getGraph(unite.getFigurine(EtypeFig.STATIC));
    			System.out.println(imgFig);
    			ImageView vueFig = new ImageView();
    			System.out.println("ok 1");
    			vueFig.setOnMousePressed(this::handleFigSelected);
    			System.out.println("ok 2");
    			vueFig.setImage(imgFig);
    			System.out.println("ok 3");
    			vueFig.visibleProperty().set(false);
    			System.out.println("ok 4");
    			vueFig.setUserData(unite);
    			System.out.println("ok 5");
    			figurines.getChildren().add(vueFig); <- c'est ici que ça coince.
    			System.out.println("ok 6");
    			unite = scenario.getPion(fig++);
    			System.out.println("ok 7");
    		}
    		// préparation annimation flamme
    		MajFlammeches();
    	}
    Avec les print sur la console j'ai pu voir que c'est à l'ajout de l'imageView que ça coince.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    figurines.getChildren().add(vueFig);
    vueFig n'est pas null ni figurines.
    J'ai du mal à comprendre pourquoi ça ne fonctionne pas dans ces conditions
    Il y a des jours où j'éprouve une haine profonde envers microsoft et Apple c'est pas mieux
    Mon modeste site et mes modestes oeuvres sont
    Rémi

  15. #15
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Dans la gestion de l'échec, log ou imprime event.getSource().getException() STP.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  16. #16
    Membre expérimenté
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 076
    Points : 1 521
    Points
    1 521
    Billets dans le blog
    5
    Par défaut
    Voici le résultat
    java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-8
    Il semblerait qu'il ne supporte pas que certaines opération soient faites en dehors du thread de l'application. Ou est ce que j'interprète mal
    Il y a des jours où j'éprouve une haine profonde envers microsoft et Apple c'est pas mieux
    Mon modeste site et mes modestes oeuvres sont
    Rémi

  17. #17
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Non c'est bien ça, certaines des actions que tu fais ne peuvent pas êtres effectuées hors du JavaFX Application Thread, la trace de l'exception t'en diras plus. Précédemment cela ne posait pas de soucis puisque tu étais dans ce thread-là mais désormais le problème se pose puisque tu as basculé ton code dans un autre thread. Il va donc falloir que tu identifies les lignes en question et que tu déplace une partie du code à nouveau dans le JFX App Thread via Platform.runLater() ou que tu fasses ces actions dans le setOnSucceeded().

    En théorie, il est tout à fait possible de manipuler des contrôles ou nœuds qui ne sont pas encore attachés à une scène hors du JFX App Thread mais en pratique à cause de bugs il y a des soucis lors de la manipulation d’infobulles (Tooltip) ou de contrôles à menu surgissant (CombBox, etc.) car ces derniers manipulent une 2nde Window et donc une scène. Certains ont été corrigé depuis et d'autres le seront dans le JDK 9 mais je n'ai pas tout testé. Ce qui est sur c'est qu'à partir du moment ou tu manipule directement une scène, ce bout de code doit s’exécuter dans le JFX App Thread.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  18. #18
    Membre expérimenté
    Avatar de Gouyon
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2003
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 1 076
    Points : 1 521
    Points
    1 521
    Billets dans le blog
    5
    Par défaut
    Bon j'ai du pain sur la planche du coup
    Merci pour le coup de main
    Il y a des jours où j'éprouve une haine profonde envers microsoft et Apple c'est pas mieux
    Mon modeste site et mes modestes oeuvres sont
    Rémi

Discussions similaires

  1. Réponses: 2
    Dernier message: 16/08/2013, 13h14
  2. Bonnes pratiques pour développer une IHM en JAVA
    Par jeromeSERRE dans le forum Interfaces Graphiques en Java
    Réponses: 13
    Dernier message: 20/11/2010, 19h17
  3. Réponses: 13
    Dernier message: 07/04/2010, 20h22
  4. Réponses: 4
    Dernier message: 01/10/2008, 08h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo