0

我在这里使用我的 JavaFx 应用程序。

我有两个班级:

我在两个不同的线程中开始这些课程。因为服务器是可阻塞的。

  • 我的 UI 类(称为 Main(我知道我需要更改它))。
  • 一个服务器类(称为 Serveur ))。

在我的服务器类中,当我使用 ServerSocket 接收字节时。

我需要在我的 UI 类中更新一个 TextFlow(称为 flowMessafe):使用 flowMessage.getChildren().add(); 我可以在我的 UI 类中毫无问题地更新这个 TextFlow。但我的服务器类我不能。

编辑:我尝试了所有的东西,但我认为我发现了一个大问题。我更新了我的 javafx 应用程序的错误实例。我用当前代码更改代码

他是我的服务器代码的一部分

My Server Constructor
public Serveur(Mediator med){
    this.med=med;
    try {
        lancer();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}


Loop to catch message or file.
for(;;){
        try {
            Thread.sleep(1L);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Attente de communication ...");

        try {
            socket = serverSocket.accept();
        } catch (IOException ex) {
            System.out.println("Can't accept client connection. ");
        }

        try {
            in = socket.getInputStream();
        } catch (IOException ex) {
            System.out.println("Can't get socket input stream. ");
        }

        byte[] bytes = new byte[16*1024];           
        while ((count = in.read(bytes)) > 0) {} 

        String mode = new String(bytes);
        String[] split = mode.split(";");
        if(split[0].compareTo("Message")==0){
            recevoirMessage();
        } else if(split[0].compareTo("Fichier")==0){
            recevoirFichier(split[2]);
        }       
        in.close();
        socket.close();

    }

当我收到一条消息时,我会转到此功能:

public void recevoirMessage() {
    output = new ByteArrayOutputStream();
    try {
        socket = serverSocket.accept();
    } catch (IOException ex) {
        System.out.println("Can't accept client connection. ");
    }
    try {
        in = socket.getInputStream();
    } catch (IOException ex) {
        System.out.println("Can't get socket input stream. ");
    }
    byte[] bytes = new byte[16*1024];
    try {
        while ((count = in.read(bytes)) > 0) {}
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    System.out.println("Message reçus");
    String recu = "Message : "+new String(bytes);
    System.out.println(recu);
    Platform.runLater(() -> {
        Label mes = new Label(new String(bytes));
        med.cli.flowMessage.getChildren().add(mes);
    });
    try {
        in.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

而在我的主要我只有空的构造函数

 public Main(){}

在我的 UI 类中,我有这个来创建我的应用程序:

'@Override
public void start(Stage primaryStage) {
    try {
        this.pStage = primaryStage;
        this.pStage = new Stage();
        idPane = new BorderPane();
        Parent page;
        page = FXMLLoader.load(getClass().getResource("/application/application.fxml"));
        this.pStage.setTitle("Messagerie");
        Scene scene = new Scene(page);
        flowMessage = new TextFlow();
        idContenuMessage= new ChoiceBox<String>();
        scrollPane= new ScrollPane();
        //flowMessage = new TextFlow();
        String css = this.getClass().getResource("application.css").
 toExternalForm();
                scene.getStylesheets().clear();
                scene.getStylesheets().add(css);
        this.pStage.setScene(scene);
        this.pStage.setResizable(false);
        this.pStage.show();
        this.pStage.setOnCloseRequest(event ->  {
            Serveur.close();
        });
    } catch (IOException e) {
        e.printStackTrace();
    }
}'

而且我不知道如何在我的服务器类中更新我的 UI TextFlow。

我看到了不同的东西,比如中介者模式,我尝试了这个,但它没有用(也许我做错了什么)。

我从这个类开始我的应用程序:

package communication;

import application.Main;
import javafx.application.Application;
import javafx.stage.Stage;

public class Mediator extends Application implements Runnable {

private Serveur serv;

public Main cli;

public Thread thread;

private Stage primaryStage;

public static void main(String args[]){
    launch(args);
}

public Mediator(){
    cli = new Main();
    thread = new Thread(this,"serv");   
    thread.start(); 
}   

@Override
public void run() {
    setServ(new Serveur(this));
}

@Override
public void start(Stage stage) throws Exception {
    primaryStage = stage;
    cli.start(primaryStage);
}

public Serveur getServ() {
    return serv;
}

public void setServ(Serveur serv) {
    this.serv = serv;
}   
}

感谢您的帮助。

4

2 回答 2

0

我会使用 Platform.runLater() 将您的 GUI 更改放在 Javafx 应用程序线程上,例如

public void recevoirMessage() {
output = new ByteArrayOutputStream();
try {
    socket = serverSocket.accept();
} catch (IOException ex) {
    System.out.println("Can't accept client connection. ");
}
try {
    in = socket.getInputStream();
} catch (IOException ex) {
    System.out.println("Can't get socket input stream. ");
}
byte[] bytes = new byte[16*1024];
try {
    while ((count = in.read(bytes)) > 0) {}
} catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}
System.out.println("Message reçus");
String recu = "Message : "+new String(bytes);
System.out.println(recu);

//inserted here
Platform.runLater(new Runnable() {
        @Override public void run() {
            //HERE I WANT TO UPDATE MY TEXTFLOW
        }
    });


try {
    in.close();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}   

}

于 2017-01-25T11:29:49.507 回答
0

首先TextFlow没有 text 属性,因此您无法为其设置该值。将Text对象添加到文本流:

Text text = new Text();    
flowMessage = new TextFlow(text);

然后创建StringProperty,将其绑定到Text组件textProperty并在 Server 类中更新此值。

应用类:

public class Mediator extends Application implements Runnable {

    private Serveur serv;

    public Main cli;

    private StringProperty textProperty = new SimpleStringProperty("text");

    public Thread thread;

    private Stage primaryStage;

    public static void main(String args[]){
         launch(args);
    }

    public Mediator(){
        cli = new Main(this,textProperty);
        thread = new Thread(this,"serv");   
        thread.start(); 
    }   

    @Override
    public void run() {
        serv = new Serveur(this,textProperty);
    }

    @Override
    public void start(Stage stage) throws Exception {
        primaryStage = stage;
        cli.start(primaryStage);
    }   
}

传递textPropertyMainServeur类。

cli = new Main(this, textProperty);
serv = new Serveur(this, textProperty);

将文本属性绑定到Text组件:

text.textProperty().bind(textProperty);

最后textProperty在您的课程中更新 JavaFX 应用程序线程Serveur

public void recevoirMessage() {
    output = new ByteArrayOutputStream();
    try {
        socket = serverSocket.accept();
    } catch (IOException ex) {
        System.out.println("Can't accept client connection. ");
    }
    try {
        in = socket.getInputStream();
    } catch (IOException ex) {
        System.out.println("Can't get socket input stream. ");
    }
    byte[] bytes = new byte[16*1024];
    try {
        while ((count = in.read(bytes)) > 0) {}
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    System.out.println("Message reçus");
    String recu = "Message : "+new String(bytes);
    System.out.println(recu);

    //inserted here
    Platform.runLater(new Runnable() {
            @Override public void run() {
                //HERE I WANT TO UPDATE MY TEXTFLOW
                textProperty.setValue(new String(bytes));
            }
        });


    try {
        in.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }   
}
于 2017-01-25T12:17:56.523 回答