JavaFX et Sockets = Pas sur le thread d'application FX


Je dois attendre qu'un programme serveur envoie des données au programme client en utilisant un socket, je dois donc l'attendre en utilisant une boucle while. Cependant, le programme client est une application JavaFX et s'il est utilisé dans une boucle while, il se figera et se bloquera, donc je mets la boucle while dans un nouveau Thread. Cependant, le corps de cette boucle while doit mettre à jour l'interface utilisateur JavaFX, ce qui ne peut pas être fait car cela provoque une exception "Not on FX application thread;", donc je ne peux pas créer un nouveau thread pour cela.

C'est mon code:

import static util.Constants.PORT;
import static util.Constants.SERVER_NAME;

public class Client extends Application {

    private static View view;
    public static Scanner in;
    public static PrintWriter out;
    private static boolean appRunning = true;

    public static void main(String[] args) {
        try {
            Socket socket = new Socket(SERVER_NAME, PORT);
            in = new Scanner(socket.getInputStream());
            out = new PrintWriter(socket.getOutputStream(), true);

            launch(args);
        } catch (IOException e) {
            System.out.println("Could not establish connection to server. Program terminating..");
            System.exit(1);
        }
    }

    @Override
    public void start(Stage window) throws Exception {
        // This is a JavaFX BorderPane that adds itself to window:
        view = new View(window);

        // ServerListener
        new Thread(() -> {
            try {
                while (appRunning) {
                    // will through exception. needs to run on Application thread:
                    parseServerMessage(Client.in.nextLine()); 
                }
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }).start();
    }

    private static String[] parseServerMessage(String message0 { 
        // update the JavaFX UI
    }
}

Et si j'ai utilisé ce code ci-dessous dans la méthode start sans le thread, l'application JavaFX se figera:

@Override
public void start(Stage window) throws Exception {
    // This is a JavaFX BorderPane that adds itself to window:
    view = new View(window);

    // causes JavaFX to freeze:
    while (appRunning) {            
        parseServerMessage(Client.in.nextLine()); 
    }
}

Mettre le fil en veille n'aide pas non plus. Comment puis-je contourner ce problème? Merci!!!!

MODIFIER la solution:

Grâce à la solution, j'ai édité mon code et maintenant cela fonctionne parfaitement. Voici la solution modifiée:

new Thread(() -> {
    while (true) {
        String serverMessage = Client.in.nextLine();
        Platform.runLater(() -> {
             parseServerMessage(serverMessage);                  
        });
    }
}).start();
Author: Mayron, 2015-11-07

1 answers

Vous pouvez jeter un oeil à Platform::runLater. Du JavaDoc:

Exécutez le Runnable spécifié sur le thread d'application JavaFX à un moment non spécifié dans le futur. Cette méthode, qui peut être appelée à partir de n'importe quel thread, postera le Runnable dans une file d'attente d'événements, puis reviendra immédiatement à l'appelant.

 1
Author: T-Fowl, 2015-11-07 09:57:13