2016-04-28 3 views
0

Javafxで作業中のIm。エコーServerClientシステムを作成しました。つまり、サーバーにデータを送信し、すべてのクライアント(ブロードキャスト)に戻します。クライアントがサーバーにデータを送信するときは正常に動作します。しかし、サーバーがクライアントにデータを送り返すと、フレームがフリーズします。ここでは、コードです: クライアント:chat()BufferedReaderがJavafxでUIをフリーズする

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package com.rajeshpatkar; 

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.net.Socket; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javafx.application.Application; 
import static javafx.application.Application.launch; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.TextArea; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 

/** 
* 
* @author Dimpi 
*/ 
public class Client extends Application{ 

    int flag = 999; 


    public void start(Stage primaryStage) throws Exception { 

     Connect cnn = new Connect(primaryStage); 
     cnn.sconnect(); 

    } 

    public static TextArea Frame(Stage primaryStage, PrintWriter nos, BufferedReader nis) throws IOException { 

     TextField tf = new TextField(); 
     TextArea ta = new TextArea(); 
     Button btn = new Button(); 
     btn.setText("Click"); 
     btn.setOnAction(new EventHandler<ActionEvent>() { 

      @Override 
      public void handle(ActionEvent event) { 

       String get = tf.getText(); 
       nos.println(get); 
       try { 
        Connect.chat(nis,ta); 
       } catch (IOException ex) { 
        Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex); 
       } 

      } 
     }); 

     BorderPane root = new BorderPane(); 
     root.setCenter(ta); 
     BorderPane panel = new BorderPane(); 
     root.setBottom(panel); 
     panel.setCenter(tf); 
     panel.setRight(btn); 
     Scene scene = new Scene(root, 300, 250); 

     primaryStage.setTitle("Hello World!"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
     return ta; 

    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     launch(args); 
    } 

} 

class Connect { 

    Stage primaryStage; 

    Connect(Stage primaryStage) { 
     this.primaryStage = primaryStage; 
    } 

    public void sconnect() throws IOException { 
     System.out.println("Client Signing IN"); 
     Socket soc = new Socket("localhost", 9081); 
     PrintWriter nos = new PrintWriter(
       new BufferedWriter(
         new OutputStreamWriter(soc.getOutputStream() 
         ) 
       ), true); 
     BufferedReader nis = new BufferedReader(
       new InputStreamReader(soc.getInputStream() 
       ) 
     ); 

     TextArea ta=Client.Frame(primaryStage, nos, nis); 

    } 

    public static void chat(BufferedReader nis,TextArea ta) throws IOException{ 

     String set = nis.readLine(); 

     while (!set.equals("End")) { 
      ta.appendText(set+"\n"); 
      set = nis.readLine(); 

     } 
    } 
} 


Server: /* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package com.rajeshpatkar; 

import static com.rajeshpatkar.Server.a1; 
import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.ArrayList; 
import javafx.application.Application; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 

/** 
* 
* @author Dimpi 
*/ 
public class Server extends Application { 
    public static ArrayList<PrintWriter> a1=new ArrayList<PrintWriter>(); 

    @Override 
    public void start(Stage primaryStage) throws IOException { 

     System.out.println("Server signing IN"); 
     ServerSocket ss = new ServerSocket(9081); 
     for (int i = 0; i < 5; i++) { 
      Socket soc = ss.accept(); 
      Conversation c = new Conversation(soc); 
      c.start(); 
     } 

    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     launch(args); 
    } 

} 

class Conversation extends Thread { 

    Socket soc; 

    Conversation(Socket soc) { 
     this.soc = soc; 
    } 

    public void run() { 
     try { 

      PrintWriter nos = new PrintWriter(
        new BufferedWriter(
          new OutputStreamWriter(soc.getOutputStream() 
          ) 
        ), true); 
      BufferedReader nis = new BufferedReader(
        new InputStreamReader(soc.getInputStream() 
        ) 
      ); 
      Server.a1.add(nos); 
      String get=nis.readLine(); 
      while(true){ 
       for(PrintWriter p:a1){ 
      System.out.println(get); 

      p.println(get); 
       } 
      get=nis.readLine(); 
      } 

     } catch (Exception e) { 

     } 

    } 
} 
+0

潜在的に長時間実行中のタスク(例えば、数秒かかる場合があります接続を取って)JavaFXのから人里離れたバックグラウンドスレッドで行う必要があり、このようなアプリケーションスレッド。これを行う方法については、[this](https://docs.oracle.com/javase/8/javafx/interoperability-tutorial/concurrency.htm)のリンクを参照してください。このロジックを実装した場合、アプリケーションはフリーズしません。 –

答えて

0

クライアントUIの凍結の問題は、あなたの方法に起因します。これはあなたのボタンによって呼び出されます。入力が発生するのを待機するメソッドreadLine()BufferedReaderが含まれています。この待機は、アプリケーションスレッドで発生するため、フリーズします。

ので、何を行うことができますすることである:あなたのボタンのEventHandlerに:のみ書き込み出力:

String get = tf.getText(); 
nos.println(get); 

が、例えば、あなたのInputStreamが入力を受信した場合、あなたのTextAreaを更新するスレッドを追加します

static void handleInput(BufferedReader nis, TextArea ta) throws IOException { 

    final Task<Void> task = new Task<Void>() { 
     @Override 
     protected Void call() throws Exception { 
      String output; 
      while ((output = nis.readLine()) != null) { 
       final String value = output; 
       Platform.runLater(new Runnable() { 

        @Override 
        public void run() { 
         ta.appendText(value + System.getProperty("line.separator")); 
        } 
       }); 
      } 
      return null; 
     } 
    }; 
    new Thread(task).start(); 
} 

、一度そのメソッドを呼び出します:

handleInput(nis, ta); 
関連する問題